将运算符与 lambda 函数关联的映射

发布于 2024-10-11 00:21:19 字数 1114 浏览 0 评论 0原文

我有一个 Haskell Map,其中包含字符串作为 key 和一些 lambda 函数作为 items 。 例如:

-- List of supported Operators -> mapping with functions
ops = Map.fromList [("+", \x y -> x + y),
                    ("-", \x y -> y - x),
                    ("*", \x y -> x * y),
                    ("/", \x y -> y / x)]

我想编写一个函数,它接受以下输入:

  • 一个表示运算符的字符串 ["+", "-", "*", "/"]
  • 两个数字

基于运算符和操作映射,该函数将评估总和/减法等。两个数字中的一个。

我尝试过类似的方法:

(Map.lookup "+" a) 1 2

但它不起作用。

错误是:

Top level:
    No instance for (Show (Integer -> Integer))
      arising from use of `print' at Top level
    Probable fix: add an instance declaration for (Show (Integer
    In a 'do' expression: print it

<interactive>:1:1:
    No instance for (Monad ((->) t))
      arising from use of `Data.Map.lookup' at <interactive>:1:1-
    Probable fix: add an instance declaration for (Monad ((->) t)
    In the definition of `it': it = (Data.Map.lookup "+" a) 1 2

...对我来说不是很有帮助。

有什么建议吗?谢谢 !

I have a Haskell Map, containing strings as keys and some lambda functions as items .
Eg.:

-- List of supported Operators -> mapping with functions
ops = Map.fromList [("+", \x y -> x + y),
                    ("-", \x y -> y - x),
                    ("*", \x y -> x * y),
                    ("/", \x y -> y / x)]

I want to write a function that takes as input:

  • A string representing an operator ["+", "-", "*", "/"]
  • Two numbers

Based on the operator and the ops map, the function will evaluate the sum/subtraction/etc. of the two numbers .

I've tried something like:

(Map.lookup "+" a) 1 2

But it's not working .

The error is:

Top level:
    No instance for (Show (Integer -> Integer))
      arising from use of `print' at Top level
    Probable fix: add an instance declaration for (Show (Integer
    In a 'do' expression: print it

<interactive>:1:1:
    No instance for (Monad ((->) t))
      arising from use of `Data.Map.lookup' at <interactive>:1:1-
    Probable fix: add an instance declaration for (Monad ((->) t)
    In the definition of `it': it = (Data.Map.lookup "+" a) 1 2

... not very helpful for me.

Any suggestions ? Thank you !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

゛清羽墨安 2024-10-18 00:21:19

Lookup 的类型为 lookup :: Ord k => k->地图ka->也许是一个。结果被包装在 Maybe 中以指示该键可能不存在于映射中。

这是一种有效的方法:

runOp :: String -> a -> a -> b
runOp key x y = case lookup key ops of
                  Just op -> op x y
                  Nothing -> error ("Couldn't find operator: " ++ key)

如果密钥不存在,这将触底。您还可以从 runOp 返回 EitherMaybe 结果,以适应密钥不存在的可能性,但这取决于您。

Maybe 定义如下:

data Maybe a = Just a | Nothing

也就是说,它要么保存结果值,要么保存空值。就像一位存在主义哲学家一样,哈斯克尔强迫你承认“无”的可能性。

lookup is of type lookup :: Ord k => k -> Map k a -> Maybe a. The result is wrapped in a Maybe to indicate that the key may not be present in the map.

Here's a way to do it that will work:

runOp :: String -> a -> a -> b
runOp key x y = case lookup key ops of
                  Just op -> op x y
                  Nothing -> error ("Couldn't find operator: " ++ key)

This will bottom out if the key is not present. You could also return an Either or Maybe result from runOp to accommodate the possibility that the key isn't present, but that's up to you.

Maybe is defined as follows:

data Maybe a = Just a | Nothing

that is, it either holds a result value or an empty value. Like an existential philosopher, Haskell forces you to acknowledge the possibility of Nothing.

不打扰别人 2024-10-18 00:21:19

首先,您显示的错误不是由您显示的代码引起的。您的代码会导致以下错误(在 ghc 中):

Couldn't match expected type `t1 -> t2 -> t'
against inferred type `Data.Maybe.Maybe

该错误是由 lookup 返回 Maybe 引起的。所以你需要先解开Maybe

First of all the error you showed is not caused by the code you showed. Your code causes the following error (in ghc):

Couldn't match expected type `t1 -> t2 -> t'
against inferred type `Data.Maybe.Maybe

That error is caused by the fact that lookup returns a Maybe. So you need to unwrap the Maybe first.

月竹挽风 2024-10-18 00:21:19
import Control.Applicative

ops :: (Fractional a) => Map.Map String (a -> a -> a)
ops = Map.fromList [("+", (+)),
                    ("-", flip (-)),
                    ("*", (*)),
                    ("/", flip (/))]

apply :: (Fractional a) => String -> a -> a -> Maybe a
apply op x y = Map.lookup op ops <*> y <*> x

因为 lookup 返回一个 Maybe a (在这种情况下,Maybe (a -> a -> a)),所以没有直接将其应用于 a 的方法。我们可以使用 <*> 将 LHS 从 mote 中拉出,将其应用到 RHS,然后将其注入回 monad。 (或者像比尔一样手动完成。)

import Control.Applicative

ops :: (Fractional a) => Map.Map String (a -> a -> a)
ops = Map.fromList [("+", (+)),
                    ("-", flip (-)),
                    ("*", (*)),
                    ("/", flip (/))]

apply :: (Fractional a) => String -> a -> a -> Maybe a
apply op x y = Map.lookup op ops <*> y <*> x

Because lookup returns a Maybe a (well, Maybe (a -> a -> a) in this case), there is no way to directly apply it to an a. We can use <*> to pull the LHS out of the mote, apply it to the RHS, and inject it back into the monad. (Or do it manually like Bill.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文