Hen*_*enk 8 haskell types algebraic-data-types
在Haskell中,您可以在没有构造函数的情况下定义代数数据类型:
data Henk
Run Code Online (Sandbox Code Playgroud)
但是没有构造函数的类型(或类型?)的目的是什么?
chi*_*chi 13
类型级机器通常需要存在类型,但从不构造这些类型的值.
例如,幻像类型:
module Example (Unchecked, Checked, Stuff()) where
data Unchecked
data Checked
data Stuff c = S Int String Double
check :: Stuff Unchecked -> Maybe (Stuff Checked)
check (S i s d) = if i>43 && ...
then Just (S i s d)
else Nothing
readFile :: Filepath -> IO (Stuff Unchecked)
readFile f = ...
workWithChecked :: Stuff Checked -> Int -> String
workWithChecked stuff i = ...
workWithAny :: Stuff any -> Int -> Stuff any
workWithAny stuff i = ...
Run Code Online (Sandbox Code Playgroud)
只要S构造函数未由模块导出,该库的用户就无法在Stuff数据类型上伪造"已检查"状态.
上面,该workWithChecked函数不必在每次调用时清理输入.用户必须已经完成它,因为它必须提供"已检查"类型的值 - 这意味着用户必须check事先调用该函数.这是一种高效且稳健的设计:我们不会在每次调用时反复重复检查,但我们不允许用户传递未经检查的数据.
需要注意的类型的值如何Checked,Unchecked都无关紧要-我们从来没有使用它们.
正如评论中提到的其他人一样,空类型还有许多其他用途,而不是幻像类型.例如,一些GADT涉及空类型.例如
data Z
data S n
data Vec n a where
Nil :: Vec Z a
Cons :: a -> Vec n a -> Vec (S n) a
Run Code Online (Sandbox Code Playgroud)
上面我们使用空类型来记录类型中的长度信息.
此外,需要类型没有构造函数来实现一些理论性的:如果我们寻找一个a这样Either a T的同构T,我们要a为空.在类型理论中,空类型通常用作逻辑上"假"命题的等价类型.