1

だから私はこのような構造を持っています:

data Maybe a = Nothing | Just a  

しかし、次のように定義された構造が必要です

data MaybeInt = Nothing | Just Int

MaybeIntを使用して定義する方法はありMaybe aますか?

4

1 に答える 1

10

を定義する方法はいくつかありますMaybeInt。私はそれらを述べて、それからいくつかの解説をします。

直接

data MaybeInt = NothingInt | JustInt Int

新しいタイプ

newtype MaybeInt = MI (Maybe Int)

同義語を入力します

type MaybeInt = Maybe Int

プレーン

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

解説

ほとんどの人はそれに精通しており、したがってそれを使用して一致させることを知っているので、最も一般的には、単純な方法を使用します。これにより、ライブラリに適しています。非常に透過的です。タイプシノニムメソッドは一般的なドキュメントメソッドですが、基本的にシノニムには役に立ちません。これにより、とは同じ型の署名を持つようになります。また、誰かが/コンストラクターを使用して照合できることを知ったらすぐに意味します。MaybeJustNothingfoo :: Int -> Maybe Intbar :: Int -> MaybeIntMaybeInt === Maybe IntJustNothing

newtypeメソッドはかなり興味深いものになります。ここでは、型を使用するたびにMI コンストラクターの「ラッピング」と「アンラッピング」を開始する必要があります。比較:MaybeInt

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

エクスポート MIしないと、誰も一致することができないので、これは素晴らしいことですMaybeInt(内部で何が起こっているかをかなりよく推測しているにもかかわらず)。これは、安定したAPIを作成するのに非常に役立ちます。のもう1つの興味深い特性は、の組み込みのものとは異なる新しいをnewtype記述できることです。たとえば、インスタンスをオーバーライドできますinstanceMaybeIntMaybeMonoid

instance Monoid MaybeInt where
  mempty = MI Nothing
  mi `mappend` (MI Nothing) = mi
  _  `mappend` mi           = mi

これは、sをラップLast aする組み込みのnewtypeとまったく同じです。Data.MonoidMaybe a

最後に、本格的なdataインスタンスを取得します。これはより冗長で、エラーが発生する可能性が高く、わずかに遅くなり(コンパイラは新しい一意のデータ型を追跡する必要があるため)、新しいコンストラクタを学習する必要があります。明らかに同一Maybe Intの機能については、それを使用する理由はまったくありません。

于 2013-02-13T16:07:51.170 に答える