来自 Data.Map 的函数 -> 可能作为 class 实例。对如何实施感到困惑
Function from Data.Map -> Maybe as a class instance. Confused about how to implement
当我完成 cis 194 (week 5) 时,我遇到了一个问题,它同时向我介绍了两个新概念,但我很难让它至少输出正确的类型。
我的目标是在最下面声明的实例中实现var
,但是我从来没有使用过作为函数的实例,也没有使用过Data.Map
,所以我我不太清楚我的解决方案语法应该是什么样子。
{-# LANGUAGE FlexibleInstances #-}
import qualified Data.Map as M
class HasVars a where
var :: String -> a
-- | This instance allows variables to be interpreted as functions from a
-- mapping of variables to Integer values to (possibly) Integer values
instance HasVars (M.Map String Integer -> Maybe Integer) where
-- not sure how to implement var here
所以,我想出了一个至少可以编译的东西。当我试图通过反复使用 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
,但似乎我给它的还不够,因为它需要一个密钥 和 Map
,我好像没有Map
。也许我对 class 实例如何工作的理解是错误的。
所以当你有
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
以及 return 和 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
不是 return 和 Maybe Integer
。它 return 是 Map String Integer -> Maybe Integer
。 a
应该是什么……正是您想要的。 var str
现在是一个接受 map 和 returns a Maybe Integer
.
的函数
M.lookup str
没有地图,是的,所以它不能 return 一个 Maybe Integer
。但它是一个 Map String Integer -> Maybe Integer
。所以 var "hello"
现在是 Map String Integer -> Maybe Integer
。 var "hello"
给你一个函数,它接受一个地图和 returns 一个 Maybe Integer
。所以如果你给 var "hello"
一张地图,比如 var "hello" mp
,那么你会得到 Maybe Integer
:D
当我完成 cis 194 (week 5) 时,我遇到了一个问题,它同时向我介绍了两个新概念,但我很难让它至少输出正确的类型。
我的目标是在最下面声明的实例中实现var
,但是我从来没有使用过作为函数的实例,也没有使用过Data.Map
,所以我我不太清楚我的解决方案语法应该是什么样子。
{-# LANGUAGE FlexibleInstances #-}
import qualified Data.Map as M
class HasVars a where
var :: String -> a
-- | This instance allows variables to be interpreted as functions from a
-- mapping of variables to Integer values to (possibly) Integer values
instance HasVars (M.Map String Integer -> Maybe Integer) where
-- not sure how to implement var here
所以,我想出了一个至少可以编译的东西。当我试图通过反复使用 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
,但似乎我给它的还不够,因为它需要一个密钥 和 Map
,我好像没有Map
。也许我对 class 实例如何工作的理解是错误的。
所以当你有
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
以及 return 和 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
不是 return 和 Maybe Integer
。它 return 是 Map String Integer -> Maybe Integer
。 a
应该是什么……正是您想要的。 var str
现在是一个接受 map 和 returns a Maybe Integer
.
M.lookup str
没有地图,是的,所以它不能 return 一个 Maybe Integer
。但它是一个 Map String Integer -> Maybe Integer
。所以 var "hello"
现在是 Map String Integer -> Maybe Integer
。 var "hello"
给你一个函数,它接受一个地图和 returns 一个 Maybe Integer
。所以如果你给 var "hello"
一张地图,比如 var "hello" mp
,那么你会得到 Maybe Integer
:D