だから私はこのような構造を持っています:
data Maybe a = Nothing | Just a
しかし、次のように定義された構造が必要です
data MaybeInt = Nothing | Just Int
MaybeInt
を使用して定義する方法はありMaybe a
ますか?
を定義する方法はいくつかありますMaybeInt
。私はそれらを述べて、それからいくつかの解説をします。
直接
data MaybeInt = NothingInt | JustInt Int
新しいタイプ
newtype MaybeInt = MI (Maybe Int)
同義語を入力します
type MaybeInt = Maybe Int
プレーン
-- just use `(Maybe Int)` wherever you would write `MaybeInt`
解説
ほとんどの人はそれに精通しており、したがってそれを使用して一致させることを知っているので、最も一般的には、単純な方法を使用します。これにより、ライブラリに適しています。非常に透過的です。タイプシノニムメソッドは一般的なドキュメントメソッドですが、基本的にシノニムには役に立ちません。これにより、とは同じ型の署名を持つようになります。また、誰かが/コンストラクターを使用して照合できることを知ったらすぐに意味します。Maybe
Just
Nothing
foo :: Int -> Maybe Int
bar :: 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を作成するのに非常に役立ちます。のもう1つの興味深い特性は、の組み込みのものとは異なる新しいをnewtype
記述できることです。たとえば、インスタンスをオーバーライドできますinstance
MaybeInt
Maybe
Monoid
instance Monoid MaybeInt where
mempty = MI Nothing
mi `mappend` (MI Nothing) = mi
_ `mappend` mi = mi
これは、sをラップLast a
する組み込みのnewtypeとまったく同じです。Data.Monoid
Maybe a
最後に、本格的なdata
インスタンスを取得します。これはより冗長で、エラーが発生する可能性が高く、わずかに遅くなり(コンパイラは新しい一意のデータ型を追跡する必要があるため)、新しいコンストラクタを学習する必要があります。明らかに同一Maybe Int
の機能については、それを使用する理由はまったくありません。