没有构造函数的代数数据类型的目的是什么?

时间:2015-10-25 22:28:52

标签: haskell types algebraic-data-types

在Haskell中,您可以定义不带构造函数的代数数据类型:

data Henk

但是没有构造函数的类型(或类型?)的目的是什么?

1 个答案:

答案 0 :(得分: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 = ...

只要模块没有导出S构造函数,该库的用户就不能伪造"已检查" Stuff数据类型的状态。

在上面,workWithChecked函数不必在每次调用时清理输入。用户必须已经完成它,因为它必须在"已检查"中提供值。 type - 这意味着用户必须事先调用check函数。这是一种高效且稳健的设计:我们不会在每次调用时反复重复检查,但我们不允许用户传递未经检查的数据。

请注意CheckedUnchecked类型的值是不重要的 - 我们从不使用它们。

正如评论中提到的其他人一样,空类型还有许多其他用途,而不是幻像类型。例如,一些GADT涉及空类型。 E.g。

data Z
data S n
data Vec n a where
  Nil  :: Vec Z a
  Cons :: a -> Vec n a -> Vec (S n) a

上面我们使用空类型来记录类型中的长度信息。

此外,需要没有构造函数的类型来实现一些理论属性:如果我们寻找a使Either a TT同构,我们需要a是空的。在类型理论中,空类型通常用作逻辑上类似的类型" false"命题。

相关问题