Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 地图数据结构的实现_Haskell_Functor - Fatal编程技术网

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)