【问题标题】:Functor error when using a data inside a data: "cannot construct the infinite type"在数据中使用数据时出现仿函数错误:“无法构造无限类型”
【发布时间】:2011-09-20 06:11:32
【问题描述】:

在进一步了解 Haskell 的类型系统时,我遇到了这个玩具问题。当我编译以下代码时:

data SingleData a = SingleData a Int String -- etc.
data DataFail a = DataFail [SingleData a]
instance Functor DataFail where
    fmap f (DataFail xs) = DataFail (map f xs)

我在 fmap 的定义中收到可怕的“发生检查:无法构造无限类型:b = SingleData b”消息。奇怪的是,如果 fmap 在实例声明之外,相同的定义将起作用:

fmapWorks f (DataFail xs) = DataFail (map f xs)

更奇怪的是,实现 Monoid 编译并且工作得很好:

instance Monoid (DataFail a) where
    mempty = DataFail []
    mappend (DataFail xs) (DataFail ys) = DataFail (xs ++ ys)

我相信这在某种程度上是在 DataFail 中使用 SingleData 的结果,因为它也可以正常工作:

data DataSuccess a = DataSuccess [a]
instance Functor DataSuccess where
    fmap f (DataSuccess xs) = DataSuccess (map f xs)

为什么 Haskell 抱怨 DataFail 的 fmap 函数,我可以做些什么来解决它?

【问题讨论】:

  • 如果您查看fmapWorks 的类型,您会发现它不是fmap 所需的类型。

标签: haskell types


【解决方案1】:

“发生检查”错误并不可怕......

问题是提供给fmap的功能。试试这个:

instance Functor SingleData where
  fmap f (SingleData a i s) = SingleData (f a) i s

instance Functor DataFail where
  fmap f (DataFail sds) = DataFail $ map (fmap f) sds

所以,实际的错误是您对map 的使用:类型不匹配。 Functor 期望它是 a -> b 类型,但您使用它的方式是 SingleData a -> SingleData b 类型; SingleData 的额外 Functor 实例允许您使用 fmap 将函数直接应用于其中的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多