Haskell 什么是数据。。。你说哈斯克尔在哪里?
我在以下网站看到了这个片段:Haskell 什么是数据。。。你说哈斯克尔在哪里?,haskell,syntax,gadt,Haskell,Syntax,Gadt,我在以下网站看到了这个片段: 数据是什么。。。你的意思是什么?我认为关键字data用于定义一个新类型。它定义了一个新类型,语法被调用 它比普通语法更通用。您可以使用GADT编写任何常规类型定义(ADT): data E a = A a | B Integer 可以写为: data E a where A :: a -> E a B :: Integer -> E a 但您也可以限制右侧的内容: data E a where A :: a -> E a B :
数据是什么。。。你的意思是什么?我认为关键字data
用于定义一个新类型。它定义了一个新类型,语法被调用
它比普通语法更通用。您可以使用GADT编写任何常规类型定义(ADT):
data E a = A a | B Integer
可以写为:
data E a where
A :: a -> E a
B :: Integer -> E a
但您也可以限制右侧的内容:
data E a where
A :: a -> E a
B :: Integer -> E a
C :: Bool -> E Bool
这在正常的ADT声明中是不可能的
有关更多信息,请查看Haskell wiki或
原因是类型安全ExecutionAST t
应该是返回t
的语句类型。如果你写一个普通的ADT
data ExecutionAST result = Return result
| WriteRegister M_Register Word8
| ReadRegister M_Register
| ReadMemory Word16
| WriteMemory Word16
| ...
然后,ReadMemory 5
将是类型为ExecutionAST t
的多态值,而不是单态的ExecutionAST Word8
,这将进行类型检查:
x :: M_Register2
x = ...
a = Bind (ReadMemory 1) (WriteRegister2 x)
该语句应从位置1读取内存并写入寄存器x
。然而,从内存中读取会产生8位单词,而写入x
则需要16位单词。通过使用GADT,您可以确保它不会编译。编译时错误比运行时错误好
GADT还包括。如果您试图以这种方式编写绑定:
data ExecutionAST result = ...
| Bind (ExecutionAST oldres)
(oldres -> ExecutionAST result)
那么它将不会编译,因为“oldres”不在范围内,您必须编写:
data ExecutionAST result = ...
| forall oldres. Bind (ExecutionAST oldres)
(oldres -> ExecutionAST result)
如果您感到困惑,请查看链接视频中更简单的相关示例。注意,也可以设置类约束:
data E a where
A :: Eq b => b -> E b
更重要的是,与常规的数据
声明不同,这实际上导致实例字典存储在类型中,允许您通过模式匹配来恢复它,就像存在类型一样。@hammar我不理解您的评论意味着什么。我不理解这样的措辞(用我的重新措辞)“通过模式匹配恢复实例字典,因为它存储在类型中”。当我进行模式匹配时,我会根据结构的形状进行解构,我不知道这是如何转化为“实例字典”的,也不知道它存储在类型中的不同之处。我应该阅读/学习什么来理解这一点?有人能解释一下,为什么这里需要GADT吗?@wliao:补充了一个解释。我发现你的解释比视频剪辑好。谢谢
data E a where
A :: Eq b => b -> E b