什么是数据…在Haskell的意思是什么?

我看到这个片段在the devlog of omegagb

data ExecutionAST result where
  Return :: result -> ExecutionAST result
  Bind :: (ExecutionAST oldres) -> (oldres -> ExecutionAST result) ->
          ExecutionAST result
  WriteRegister :: M_Register -> Word8 -> ExecutionAST ()
  ReadRegister :: M_Register -> ExecutionAST Word8
  WriteRegister2 :: M_Register2 -> Word16 -> ExecutionAST ()
  ReadRegister2 :: M_Register2 -> ExecutionAST Word16
  WriteMemory :: Word16 -> Word8 -> ExecutionAST ()
  ReadMemory :: Word16 -> ExecutionAST Word8

数据是什么意思?我认为关键字数据用于定义一个新类型。

它定义了一个新类型,语法称为generalized algebraic data type

它比普通语法更通用。您可以使用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或this video

原因是类型安全。 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还包括existential types.如果您尝试以这种方式写入绑定:

data ExecutionAST result = ... 
                           | Bind (ExecutionAST oldres)
                                  (oldres -> ExecutionAST result)

那么它不会编译,因为“oldres”不在范围内,你必须写:

data ExecutionAST result = ...
                           | forall oldres. Bind (ExecutionAST oldres)
                                                 (oldres -> ExecutionAST result)

如果您感到困惑,请检查链接的视频以获得更简单的相关示例。

http://stackoverflow.com/questions/8245288/what-does-data-where-mean-in-haskell

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:什么是数据…在Haskell的意思是什么?