首页 > 解决方案 > 为什么在haskell的类型类定义中不能使用类型构造函数?

问题描述

data LinkedList a = Empty | Cons a (LinkedList a)   deriving (Eq, Show)

instance  Foldable LinkedList where
  foldMap _ Empty  = mempty
  foldMap f (a `Cons` ll) =  LinkedList (f a)  (foldMap f ll)

似乎 LinkedList 构造函数不在范围内?为什么?

编译器错误:

        Data constructor not in scope: LinkedList :: m -> m -> m
   |        
17 |   foldMap f (a `Cons` ll) =  LinkedList (f a)  (foldMap f ll)
   |                              ^^^^^^^^^^
            
            

我搜索了一个解决方案,似乎我应该使用“映射”而不是构造函数。这非常令人困惑。我没有在任何地方定义任何 Monoid 类型类。

你能解释为什么mappened而不是构造函数吗?Monoid函数mappenedmempty定义在哪里?

编辑 - - - - - - - - - - - - - - - - - - - - - - - - - --------------------

当我从 mappened 改回来时,我犯了一个错误。对不起,但正确的问题是:

instance  Foldable LinkedList where
  foldMap _ Empty  = mempty
  foldMap f (a `Cons` ll) =  Cons (f a)  (foldMap f ll)

编译器错误:

     • Occurs check: cannot construct the infinite type:
        m ~ LinkedList m
    • In the second argument of ‘Cons’, namely ‘(foldMap f ll)’
      
   |        
17 |   foldMap f (a `Cons` ll) =  Cons (f a)  (foldMap f ll)
   |            

                           ^^^^^^^^^^^^

为什么我不能递归使用 foldMap?以及 Monoid 函数的定义位置。

标签: haskellconstructortypeclassmonoids

解决方案


data LinkedList a = Empty | Cons a (LinkedList a)

你有

  • LinkedList,它是一个类型构造函数:它将一般类型 a作为参数并返回类型LinkedList a
  • Cons,它是一个构造函数:它接受一个通用类型的和一个类型的作为参数。aLinkedList a

另一方面,这里

  foldMap f (a `Cons` ll) =  LinkedList (f a)  (foldMap f ll)

您使用LinkedList的好像是一个构造函数,这是错误的。


推荐阅读