Haskell 地图数据结构的实现
这个Haskell 地图数据结构的实现,haskell,functor,Haskell,Functor,这个函子实例有什么问题 data Map k v = Map [(k, v)] deriving (Show, Eq) instance Functor (Map a) where fmap _ (Map []) = Map [] fmap f (Map xs) = Map xs' where xs' = map (\(k, v) -> (f k, v)) xs 如果我们编译这个,我们会得到错误: <interactive>:6:21: error:
函子
实例有什么问题
data Map k v = Map [(k, v)] deriving (Show, Eq)
instance Functor (Map a) where
fmap _ (Map []) = Map []
fmap f (Map xs) = Map xs'
where xs' = map (\(k, v) -> (f k, v)) xs
如果我们编译这个,我们会得到错误:
<interactive>:6:21: error:
• Couldn't match type ‘a1’ with ‘b’
‘a1’ is a rigid type variable bound by
the type signature for:
fmap :: forall a1 b. (a1 -> b) -> Map a a1 -> Map a b
at <interactive>:5:3
‘b’ is a rigid type variable bound by
the type signature for:
fmap :: forall a1 b. (a1 -> b) -> Map a a1 -> Map a b
at <interactive>:5:3
Expected type: Map a b
Actual type: Map a a1
• In the expression: Map xs'
In an equation for ‘fmap’:
fmap f (Map xs)
= Map xs'
where
xs' = map (\ (k, v) -> (k, v)) xs
In the instance declaration for ‘Functor (Map a)’
• Relevant bindings include
xs' :: [(a, a1)] (bound at <interactive>:7:11)
xs :: [(a, a1)] (bound at <interactive>:6:15)
f :: a1 -> b (bound at <interactive>:6:8)
fmap :: (a1 -> b) -> Map a a1 -> Map a b
(bound at <interactive>:5:3)
但很明显,您的输出类型是映射a1
,因此您没有满足这些合同。如果我们进一步研究,我们会发现map(\(k,v)->(k,v))xs
实际上没有什么作用(除了在新的元组中重新打包数据)。输出元组的类型应该是(a,b)
,而不是(a,a1)
(a1
是映射中值的原始类型)
因此,我们应该对值应用f
,如:
instance Functor (Map a) where
fmap _ (Map []) = Map []
fmap f (Map xs) = Map xs'
where xs' = map (\(k, v) -> (k, f v)) xs
实例函子(映射a),其中
fmap(Map[])=Map[]
fmap f(地图xs)=地图xs'
其中xs'=map(\(k,v)->(k,f v))xs
或者以更干净的方式:
instance Functor (Map a) where
fmap f (Map xs) = Map (fmap (fmap f) xs)
实例函子(映射a),其中
fmap f(Map xs)=Map(fmap(fmap f)xs)
请注意,您不需要在这里实现两种不同的情况(一种用于空列表,另一种用于非空列表),因为空列表上的map
(或fmap
)是空列表。您为什么要问?(\(k,v)->(k,v))
没有任何作用。你好像忘了在那里使用f
。编译器给出了一个错误。通常这是调试的良好起点。您将f应用于k而不是v。是否可以在键上应用该函数?@Barnabsmarkus:否,因为函子f
,需要一个带有一个类型参数的f
,这里是值。当然,您可以重新设计它,并定义一个Map vk
,这样您就可以fmap
对值进行定义,但不能像Map
当前的定义方式那样。非常感谢!这是我最初的问题,但不知何故,我在这里发布时犯了一个错误!
instance Functor (Map a) where
fmap f (Map xs) = Map (fmap (fmap f) xs)