ehirdの答えを受け入れます。これを書いているのは、コメントで言及したスマートデストラクタを説明できるようにするためであり、説明をコメントに収めることができません。
あなたがタイプを持っているとしましょう:
data T x y z = A | B x | C y z
ehird は、コンストラクターを抽象化する方法を既に説明しました。これは、単に「スマートな」コンストラクターを提供するためのものです。あなたが述べたように、これにはコンストラクターを非表示にする必要があり、それらを使用してパターン マッチを行うことはできません。ただし、「スマート」デストラクタを使用してこれを解決できます。これは、考えられるすべてのコンストラクタに対するパターン マッチングと同等です。
これを説明するために、まず、コンストラクターが公開されている場合に T 型の関数を記述する方法から始めましょう。
myFunction :: T x y z -> d
myFunction t = case t of
A -> f1
B x -> f2 x
C y z -> f3 y z
関数の型シグネチャから、f1
、f2
、およびの型は次のようでf3
なければならないことがわかります。
f1 :: d
f2 :: x -> d
f3 :: y -> z -> d
したがって、一般化myFunction
してスマート デストラクタにするにはf1
、 、f2
、およびf3
をパラメータとして渡すだけです。
smartDestructor :: d -> (x -> d) -> (y -> z -> d) -> t -> d
smartDestructor f1 f2 f3 t = case t of
A -> f1
B x -> f2 x
C y z -> f3 y z
したがって、をエクスポートするsmartDestructor
と、基本的に、コンストラクターにアクセスする必要なく、型に対してパターン マッチを行うことができます。
maybe
以前にまたは関数を使用しeither
たことがある場合は、スマート デストラクタを使用したことになりますが、その場合、コンストラクタは非表示にならないため、主に便利な関数として提供されます。
maybe :: b -> (a -> b) -> Maybe a -> b
maybe f1 f2 m = case m of
Nothing -> f1
Just a -> f2 x
either :: (a -> c) -> (b -> c) -> Either a b -> c
either f1 f2 e = case e of
Left a -> f1 a
Right b -> f2 b
あなたの場合、スマートデストラクタの目的は、コンストラクタを非表示にしてコンストラクタを公開しないようにすることです。