doo*_*fin 1 haskell types algebraic-data-types
一些代数数据类型..
data Cell0=Cell0 {c0str::Text,c0uid::Uid}
deriving (Data,Typeable,Show)
data Cell1=Cell1 {c1start::Uid,c1end::Uid,c1str::Text,c1uid::Int}
deriving (Data,Typeable,Show)
data Cell2=Cell2 {c2start::Uid,c2end::Uid,c2str::Text,c2uid::Int}
deriving (Data,Typeable,Show)
data Acell=Cell0|Cell1
Run Code Online (Sandbox Code Playgroud)
但最后一行导致编译错误“Cell0 的多个声明”
我也试过这样的:
data A=Aasdfdsf {sdf::Text}
deriving (Data,Typeable,Show)
data B=Bsdfsd
data AB=A|B
Run Code Online (Sandbox Code Playgroud)
它编译!好奇怪。。
data Acell=Cell0|Cell1
Run Code Online (Sandbox Code Playgroud)
这不是 ADT 的工作方式。
当你写的时候你在想什么似乎是“一个 Acell 要么是一个 Cell0 要么是一个 Cell1”。但是 Haskell 规范说这实际上意味着“引入一个新类型 Acell,并引入一个新的不带参数的构造函数 Cell0,并引入一个不带参数的新构造函数 Cell1”。
因此,您的类型定义根本不包含对类型 Cell0 的引用,但它引入了一个新的构造函数 Cell0,该构造函数与名为 Cell0 的现有构造函数发生冲突。因此错误。
你有第二个例子data AB=A|B并不能正常工作。它可以编译,但是如果您尝试过它,您会发现不能将 type 的元素放入Atype AB。AB 要么是构造函数 A(不包含其他数据),要么是构造函数 B(不包含其他数据);与 A 型和 B 型完全无关。
问题是 ADT标记了工会;在data声明的每个分支(由 分隔|)中,必须有一个新的构造函数,然后是将存储在构造函数中的类型。因此,例如,您可以说:
data Acell = Acell0 Cell0 | Acell1 Cell1
Run Code Online (Sandbox Code Playgroud)
构造函数用作“标签”,允许您在不查看内部数据的情况下判断正在使用哪个“分支”,即使这些分支实际上存储了相同的数据(例如data Foo = L Integer | R Integer)。没有办法拥有未标记的联合并忽略构造函数。
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |