定义新的haskell类型

时间:2016-11-25 08:49:31

标签: haskell types

我是哈斯凯尔的新手。我有两个问题,但它们有点相关。

是否可以定义一个不包括特定整数的整数类型,例如零。或者只是正数。

data allIntsButZero = ..? { a /= 0 | for all a in Int} ??
data positiveInts   = ..? { a >= 0 | for all a in Int} ??

简而言之,我可以将类型定义为另一种类型的子集吗?

其次,我可以定义一个强加逻辑的类型吗? e.g。

type doublePair = (Int, Int * 2) {- where snd is always 2 times of fst -}
data validDDMMYYYY = G Int Int Int {- where complies to gregorian calendar -}

1 个答案:

答案 0 :(得分:3)

type doublePair这些确实没有意义。如果snd始终是fst的两倍,那么它实际上并不包含任何信息!所以,这种类型肯定更好地表达为

newtype DoubleableInt = DoubleableInt {getDoubleableInt :: Int}

其他人确实有道理,但我认为你仍然有点遗漏抽象点。类型validDDMMYYYY可能应该表示 date ,即一个时间点。如何表示这不应该是用户的关注:如果某个库依赖于某种表示,它应该只提供专门的“智能构造函数”来确保良好的形成。像

newtype AllIntsButZero = AllIntsButZero {getNonzeroInt :: Int}

mkNonzeroInt :: Int -> Maybe AllIntsButZero
mkNonzeroInt 0 = Nothing
mkNonzeroInt n = AllIntsButZero n

然后,您可以拒绝导出AllIntsButZero构造函数(这将允许用户形成错误的AllIntsButZero 0):

module RestrictedNumbers (AllIntsButZero, getNonzeroInt, mkNonzeroInt) where

这样,用户只会将AllIntsButZero视为“黑匣子”,而且可以使用它们的函数可以保证产生格式良好的值。