[英]Alias for datatypes in Haskell
So I've got a structure like this: 所以我有一个这样的结构:
data Maybe a = Nothing | Just a
but I want a structure that is defined as 但我想要一个定义为的结构
data MaybeInt = Nothing | Just Int
is there a way to define MaybeInt
using Maybe a
, and if so how? 有没有一种方法可以使用Maybe a
定义MaybeInt
?
There are a few ways to define MaybeInt
. 有几种方法可以定义MaybeInt
。 I'll state them then have some commentary. 我先说一下,然后再做些评论。
Direct 直接
data MaybeInt = NothingInt | JustInt Int
Newtype 新类型
newtype MaybeInt = MI (Maybe Int)
Type synonym 类型同义词
type MaybeInt = Maybe Int
Plain 平原
-- just use `(Maybe Int)` wherever you would write `MaybeInt`
Commentary 评论
Most commonly, one would use the plain method since most people are familiar with Maybe
and thus know to use Just
and Nothing
to match it. 最常见的是,因为大多数人都熟悉Maybe
,因此知道使用Just
and Nothing
来匹配它,所以将使用简单方法。 This makes it good for libraries—very transparent. 这非常适合库-非常透明。 The type synonym method is a common documentation method, but is basically useless for your synonym. 类型同义词方法是一种常见的文档编制方法,但是对于您的同义词基本上是没有用的。 It makes it so that foo :: Int -> Maybe Int
and bar :: Int -> MaybeInt
have identical type signatures. 它使得foo :: Int -> Maybe Int
bar :: Int -> MaybeInt
foo :: Int -> Maybe Int
和bar :: Int -> MaybeInt
具有相同的类型签名。 It also means that as soon as someone knows that MaybeInt === Maybe Int
they can use the Just
/ Nothing
constructors for matching. 这也意味着,只要有人知道MaybeInt === Maybe Int
他们就可以使用Just
/ Nothing
构造函数进行匹配。
The newtype method gets fairly interesting. newtype方法变得相当有趣。 Here you have to begin "wrapping" and "unwrapping" the MI
constructor every time you want to use the MaybeInt
type . 在这里,每次要使用MaybeInt
类型时,都必须开始“包装”和“展开” MI
构造函数 。 Compare: 相比:
baz :: MaybeInt -> Bool
baz (MI Nothing) = False
baz (MI (Just int)) = True
this is nice because if you don't export MI
then nobody will be able to match on MaybeInt
(despite having a pretty good guess at what's going on inside of it). 这很好,因为如果您不导出 MI
那么没人会在MaybeInt
上进行匹配(尽管可以很好地猜测其中发生了什么)。 This is really useful for making stable APIs. 这对于制作稳定的API确实很有用。 Another interesting property of newtype
is that you can write new instance
s for MaybeInt
which are different from Maybe
's built-in ones. 另一个有趣的特性newtype
是,你可以写新的instance
对于s MaybeInt
这是从不同的Maybe
的内置的。 For instance, you could override the Monoid
instance 例如,您可以覆盖Monoid
实例
instance Monoid MaybeInt where
mempty = MI Nothing
mi `mappend` (MI Nothing) = mi
_ `mappend` mi = mi
which is just the same as the Last a
newtype built-in to Data.Monoid
which wraps Maybe a
s. 这与Data.Monoid
内置的Last a
Data.Monoid
,后者包装Maybe a
。
Finally, we get the full-blown data
instance. 最后,我们获得了完整的data
实例。 It's more verbose, more likely to error, marginally slower (since the compiler has to track a new, unique data type), and requires that people learn new constructors. 它更冗长,更容易出错,速度稍慢(因为编译器必须跟踪新的唯一数据类型),并且要求人们学习新的构造函数。 For functionality so obviously identical to Maybe Int
there's really no reason to use it at all. 对于与Maybe Int
如此明显相同的功能,实际上根本没有理由使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.