当我在cis 194 (week 5)工作时,我遇到了一个问题,它同时向我介绍了两个新概念,而且我很难做到,至少输出正确的类型。
我的目标是在底部声明的实例中实现phony
,但是,我之前从未使用过函数的实例,也没有使用var
,所以我是不太清楚我的解决方案语法应该是什么样的。
Data.Map
答案 0 :(得分:4)
所以当你有
时class HasVars a where
var :: String -> a
这意味着,对于任何实例a
,您都有一个函数var :: String -> a
。
所以,如果Map String Integer -> Maybe Integer
是一个实例,那么这意味着你必须提供一个函数:
var :: String -> (Map String Integer -> Maybe Integer)
请记住(->)
来自右侧,因此这里的括号是可选的 -
var :: String -> Map String Integer -> Maybe Integer
因此,var
是一个采用String
和Map
并返回Maybe Integer
的函数。我们来写吧!
instance HasVars (Map String Integer -> Maybe Integer) where
-- var :: String -> Map String Integer -> Maybe Integer
var str mp = M.lookup str mp
这很有效!
修改:回答问题
我看到你想知道为什么
var str = M.lookup str
的工作原理。请注意,M.lookup str
不会返回Maybe Integer
。它返回Map String Integer -> Maybe Integer
。这正是a
应该是什么......正是你想要的。 var str
现在是一个获取地图并返回Maybe Integer
。
M.lookup str
没有地图,是的,所以它无法返回Maybe Integer
。但它是Map String Integer -> Maybe Integer
。所以var "hello"
现在是Map String Integer -> Maybe Integer
。 var "hello"
为您提供了一个获取地图并返回Maybe Integer
的函数。因此,如果您提供var "hello"
地图,例如var "hello" mp
,那么您会获得Maybe Integer
:D
答案 1 :(得分:1)
所以,我想出了一些至少可以编译的东西。当我试图通过反复使用Maybe
作为构造函数来解决这个问题时,我不必要地引起了一些混乱,并且茫然地盯着它没有定义的错误消息。 Just
是Maybe
的构造函数,Maybe
不是构造函数;太多次了......
其次,我使用lookup ...
代替M.lookup ...
完全填空,导致意外的类型结果。
除了那些绊脚石,这就是我试过的东西
instance HasVars (M.Map String Integer -> Maybe Integer) where
var str = M.lookup str -- can be Eta-reduced
这是编译,但对我来说没有太大意义的是,根据实例声明,我不应该提供键值Map
吗? M.lookup
会回复一个Maybe Integer
,但似乎我没有足够的做到这一点,因为它需要一个键和一个{{1我似乎没有Map
。也许我对类实例如何工作的理解是关闭的。