Generics Haskell中的类型模式和泛型类

Generics Haskell中的类型模式和泛型类,generics,reflection,haskell,Generics,Reflection,Haskell,我试图理解Haskell中的类型模式和泛型类,但似乎无法理解 有人能用外行的话解释一下吗 我在[1]中读到过 “为了将函数一般地应用于所有数据类型,我们以统一的方式查看数据类型:除了基本的预定义类型,如Float、IO和→, 每个Haskell数据类型都可以被视为可能标记产品的标记总和。” 然后提到了单元,:*:和:+:。Haskell中的所有数据类型都是上述版本的自动数据类型吗?如果是,我如何确定特定数据类型是如何用:*:等表示的?haskell.org上的泛型类用户指南(第7.16章)没有提

我试图理解Haskell中的类型模式和泛型类,但似乎无法理解

有人能用外行的话解释一下吗

我在
[1]
中读到过

“为了将函数一般地应用于所有数据类型,我们以统一的方式查看数据类型:除了基本的预定义类型,如Float、IO和→, 每个Haskell数据类型都可以被视为可能标记产品的标记总和。”

然后提到了
单元
:*:
:+:
。Haskell中的所有数据类型都是上述版本的自动数据类型吗?如果是,我如何确定特定数据类型是如何用
:*:
等表示的?haskell.org上的泛型类用户指南(第7.16章)没有提到预定义的类型,但是如果类型模式应该是详尽的,那么它们不应该在每个函数中处理吗

[1] 比较Haskell、Ralf Hinze、Johan Jeuring和Andres Löh中的泛型编程方法


他们是手工做的。它类似于布尔代数中使用的“积和”形式。由于每个代数数据类型都是由和和和积构成的,因此转换可能与布尔代数中的转换非常相似,只是在这种情况下,它们提取了结构并丢弃了一些语义

他们的例子是
列表a
,最初定义为

data List a = Nil | Cons a (List a)
但是变成了

data List a = Unit :+: (a :*: (List a)).
我只是浏览了一下这篇文章,但是我看到了从声明中提取类型构造函数和使用
+
*
运算符构建所有内容的一些价值

在使用这些更通用的结构类型之前,它们定义了一个同构,以表明它们确实是相同的。它们还包括带有记录和构造函数名称的标记,我将省略这些:

from Nil = Unit
from (Cons x y) = x :*: y
to Unit = Nil
to (x :*: y) = Cons x y

他们是手工做的。它类似于布尔代数中使用的“积和”形式。由于每个代数数据类型都是由和和和积构成的,因此转换可能与布尔代数中的转换非常相似,只是在这种情况下,它们提取了结构并丢弃了一些语义

他们的例子是
列表a
,最初定义为

data List a = Nil | Cons a (List a)
但是变成了

data List a = Unit :+: (a :*: (List a)).
我只是浏览了一下这篇文章,但是我看到了从声明中提取类型构造函数和使用
+
*
运算符构建所有内容的一些价值

在使用这些更通用的结构类型之前,它们定义了一个同构,以表明它们确实是相同的。它们还包括带有记录和构造函数名称的标记,我将省略这些:

from Nil = Unit
from (Cons x y) = x :*: y
to Unit = Nil
to (x :*: y) = Cons x y

好吧,你可能不喜欢听这个,但你需要听听这是一篇研究论文。这不是关于如何完成的说明手册或备忘单。这是一个关于如何使用Haskell已经提供给您的新形式(即,它不是标准库…但…它是一种一次创建一个库的方法,因此您以后不需要重新创建)

这就像编写代码来生成堆栈或队列一样——这是一个练习。如果你能用它来做一些真实的事情,那么你就有了更大的力量,但总的来说,它只是一个说明,或者你能用语言做什么,而不是指导你该如何去做

这并不是说论文只是一个玩具练习,永远不能用于任何重要的事情,只是他们的目的是展示你如何组织你的程序,这样你就不会写那么多的样板文件,或者重复你自己的工作,而没有任何节省

至于{|…}(…)东西,这是作者谈论类型和该类型的值的方式。具体来说,
{|…|}
是作者将类型表示为值的一种方式。只是挥手表示怀疑。这是一种玩“让我们假装”的复杂方式。作者说,“看,Haskell不允许我们将类型传递给函数,所以我们将使用这种形式作为一种简写方式来表示,”还记得我们刚刚通过的那一节,展示了如何获得一个包含所有Con(structor)和Label类型的类型表示吗?假设我们这样做了,对于某个类型
a
的结果就是我们所说的
{a |}
“它是一种表示函数(编码、解码、映射、showP等)正在获取和使用某个术语的类型和值的符号

关于你的其他问题:

  • 难道所有的模式匹配都不会结束吗
    List
    s如果我开始重新定义
    列表
    ? 如果您重新定义它的方式不再匹配它的“当前”定义,那么它当然会!(提示:这就是
    {|…|}
    表单的要点:您的函数知道您正在使用的类型,所以它也知道如何使用它!)

  • 甚至可以重新定义数据吗 类型? 当然是!(我觉得自己像是#haskell@FAQ的回答者,这里…)请看上面的提示:

  • 我希望这能回答你的问题。如果你有更多的问题,或者想和一个活人讨论一下,你可以随时访问freenode上的IRC频道(以防万一你不知道我为什么在上面的句子中加上那个哈希标记和“at”符号)。
    非常友好,乐于助人,让各地的巨魔感到沮丧!:)

    好吧,你可能不喜欢听这个,但你需要听它。这是一篇研究论文。这不是关于如何完成的指导手册或备忘单。这是一篇关于如何使用Haskell已经提供的新形式的具体探索使您满意(即,它不是标准库…但…它是一种制作一次的方法,所以您以后不需要重新制作)

    这就像编写代码来生成堆栈或队列一样——这是一个练习