Ben*_*Ben 1 dictionary haskell maybe
我是一个Haskell新手试图了解如何使用Data.Map结构,懒惰的评估和Maybe类型.
在Python中,我可以定义一个字典结构,其值是函数.给定一个键我就可以使用相应的函数:
d = {"+": lambda x,y: x+y}
def f(key, v1, v2):
if key in d:
return d[key](v1, v2)
else:
return 0
Run Code Online (Sandbox Code Playgroud)
我试图在Haskell中做类似的事情,但它不编译.
d = Map.fromList [('+', (+))]
f :: Char -> Integer -> Integer -> Integer
f key v1 v2 =
if k == Nothing
then 0
else f v1 v2
where
k = Map.lookup key d
(Just f) = k
Run Code Online (Sandbox Code Playgroud)
这不会编译并返回错误之类的
No instance for (Eq (Integer -> Integer -> Integer))
Run Code Online (Sandbox Code Playgroud)
我相信这是因为Map.lookup '+' d只返回一个Maybe (Integer -> Integer -> Integer)not (Just (+))或的实例Nothing.我认为这与懒惰的评估有关.
是否有像Haskell一样的方式来做这种事情?我是否正确使用了Maybe类型?我可以强制评估查找吗?
这是因为我试图在Haskell中实现反向抛光计算器.我用字典来组织我可以使用的功能.我找到了一个很好的解决方案(https://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm#Haskell)没有字典,但现在我只想了解如何正确访问Haskell中的值Data.Map.
问题是这个表达式: k == Nothing
它需要k支持平等测试.类型k是Maybe (Integer -> Integer -> Integer).Maybe T支持等式测试,如果T有,但Integer -> Integer -> Integer不支持:您无法比较函数是否相等.所以整个表达式都没有进行类型检查.
我不知道" 实例Maybe (Integer -> Integer -> Integer) " 是什么意思:类有实例(类型),但Maybe (Integer -> Integer -> Integer)不是类,它是普通类型.有问题的类是Eq(提供==方法).问题是函数类型没有Eq实例.这与懒惰评估无关.
解决方案是使用模式匹配:
f key v1 v2 =
case Map.lookup key d of
Nothing -> 0
Just f -> f v1 v2
-- but consider naming 'f' something else;
-- the surrounding function is already called 'f'
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用其中一个Maybe辅助函数:
f key v1 v2 =
maybe 0 (\f -> f v1 v2) (Map.lookup key d)
Run Code Online (Sandbox Code Playgroud)
甚至:
f key v1 v2 =
fromMaybe (\_ _ -> 0) (Map.lookup key d) v1 v2
Run Code Online (Sandbox Code Playgroud)