【问题标题】:Understanding a functor instance of my custom data type了解我的自定义数据类型的函子实例
【发布时间】:2021-09-21 03:02:08
【问题描述】:

我有这种数据类型:

data Arf a = Ser a [Arf a] deriving Show

当实例化 Functor 时,此代码有效:

instance Functor Arf where
    fmap f [] = []
    fmap f (Ser x xs) = Ser (f x) (map (fmap f) x)

为什么在Ser 的第二个参数中使用(map (fmap f) x) 而不是(fmap f x)

【问题讨论】:

  • 很遗憾您的代码不起作用。事实上fmap f [] = [] 会抛出一个错误(除了 Fyodor Soikin 指出的错误)。请点击Edit 并更新您的问题。
  • 您可以通过在 ghci 中运行 :set -XDeriveFunctor -ddump-deriv 然后运行 ​​data Arf a = Ser a [Arf a] deriving Functor 来查看 ghc 如何写入 Functor 实例
  • fmap f [] 除了不进行类型检查之外完全是无关的。 Arf 只有一个构造函数(Ser),所以只定义一种情况。 没有没有“空”Arf a 值。

标签: haskell functor


【解决方案1】:

我认为您的代码中有一个错字:在最后一行的最后,应该是 xs 而不是 x

说完这些,让我们来讨论一下地图吧。

内部fmap 将函数f 映射到Arf a 类型。所以你可能会在这种情况下观察到:

     f ::     a ->     b
fmap f :: Arf a -> Arf b

但是那些Arf a 值在一个列表中!那么如何应用一个函数,将单个 Arf a 值转换为这些值的整个列表,并转换它们中的每一个?当然是map

所以外层map 适用于整个列表:

          f ::       a  ->      b
     fmap f ::   Arf a  ->  Arf b
map (fmap f) :: [Arf a] -> [Arf b]

【讨论】:

    【解决方案2】:

    (根据 Fyodor 的评论修复...)

    为什么在Ser 的第二个参数中使用(map (fmap f) xs) 而不是(fmap f xs)

    Ser 的第二个参数是什么?这是一个[Arf a],即Arfs 的列表。

    如何将f 应用于xs 列表中的元素?你做map ??? xs...

    但是??? 函数是什么?

    好吧,您希望它在 Arfs 内部应用 f,因此您需要它递归调用您定义的相同 fmap 函数,因此是 ??? === fmap f

    因此map (fmap f) xs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      • 1970-01-01
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多