Haskell中数据类型的别名

时间:2013-02-13 15:00:38

标签: haskell types

所以我有这样的结构:

data Maybe a = Nothing | Just a  

但我想要一个定义为

的结构
data MaybeInt = Nothing | Just Int

有没有办法使用MaybeInt来定义Maybe a,如果有,怎么办?

1 个答案:

答案 0 :(得分:9)

有几种方法可以定义MaybeInt。我会说他们然后有一些评论。

直接

data MaybeInt = NothingInt | JustInt Int

NEWTYPE

newtype MaybeInt = MI (Maybe Int)

输入同义词

type MaybeInt = Maybe Int

-- just use `(Maybe Int)` wherever you would write `MaybeInt`

<强>评论

最常见的是,人们会使用普通方法,因为大多数人都熟悉Maybe,因此知道使用JustNothing来匹配它。这使它对图书馆有益 - 非常透明。 类型同义词方法是一种常见的文档方法,但对于您的同义词基本上没用。它使foo :: Int -> Maybe Intbar :: Int -> MaybeInt具有相同的类型签名。这也意味着只要有人知道MaybeInt === Maybe Int他们就可以使用Just / Nothing构造函数进行匹配。

newtype 方法非常有趣。每次要使用MI 类型时,您必须开始“包装”和“展开”MaybeInt 构造函数。比较:

baz :: MaybeInt -> Bool
baz (MI Nothing) = False
baz (MI (Just int)) = True

这很好,因为如果你没有导出 MI那么就没有人可以在MaybeInt上匹配(尽管对内部发生的事情有很好的猜测)它)。这对于制作稳定的API非常有用。 newtype的另一个有趣属性是,您可以为instance编写与MaybeInt内置的Maybe不同的新Monoid。例如,您可以覆盖instance Monoid MaybeInt where mempty = MI Nothing mi `mappend` (MI Nothing) = mi _ `mappend` mi = mi 实例

Last a

与包含Data.Monoid的{​​{1}}内置的Maybe a新类型相同。

最后,我们得到了成熟的data实例。它更冗长,更容易出错,速度稍慢(因为编译器必须跟踪新的,唯一的数据类型),并要求人们学习新的构造函数。对于明显与Maybe Int完全相同的功能,根本没有理由使用它。