haskell generics文档不正确?

时间:2017-08-19 13:01:50

标签: haskell

我一直在浏览GHC Generics documentation here,似乎示例代码不正确。我遇到麻烦的部分是:

type RepUserTree a =
  -- A UserTree is either a Leaf, which has no arguments
      U1
  -- ... or it is a Node, which has three arguments that we put in a product
  :+: a :*: UserTree a :*: UserTree a

假设(:*:)类型运算符被定义为data (:*:) f g p = f p :*: g p,正如预期的那样,上面的代码位给出了类错误:

 Blockquotetest.hs:26:13: error:
    • Expecting one fewer argument to ‘UserTree a’
      Expected kind ‘* -> *’, but ‘UserTree a’ has kind ‘*’
    • In the first argument of ‘:*:’, namely ‘UserTree a’
      In the second argument of ‘:*:’, namely ‘UserTree a :*: UserTree a’
      In the second argument of ‘:+:’, namely
        ‘a :*: (UserTree a :*: UserTree a)’

文档是否不正确?我错过了一个扩展,使上述工作?我不确定如何改变上面的内容进行编译。

1 个答案:

答案 0 :(得分:0)

这只是一个虚拟的例子,让您了解它正在做什么,因为细节有点复杂。但是可能值得理解为什么它不能编译,因为如果你想在Haskell中进行任何类型级别的编程,那么理解在这些情况下出了什么问题是很好的。

如果查看(:+:)(:*:)的类型参数,可以看到它们分别采用三种类型f g p。他们都很善良* -> * -> * -> *

data (:+:) f g p = L1 (f p) | R1 (g p)
data (:*:) f g p = f p :*: g p

p已提供给fg,因此我们知道fg必须至少是* -> *种。 UserTree类型的类型为* -> *

data UserTree a = Node a (UserTree a) (UserTree a) | Leaf

但是在声明中我们有UserTree a,它是*种类,而什么(:* :)期待至少有两种事物* -> *

type RepUserTree a = U1 :+: a :*: UserTree a :*: UserTree a

如果你删除a,你就可以编译它。

type RepUserTree a = U1 :+: a :*: UserTree :*: UserTree

现在查看U1K1M1,它们都以p参数结尾。请注意,在RealRepUserTree示例中,U1K1M1所有类型都少于一个。这些符合(:+:)(:*:)的要求。