2017-02-25 16 views
4

私は型クラスとGADTSの違いを理解しようとしています。特に、-XMultiParamTypeClasses拡張子を使用している場合は、タイプクラスまたはGADTを使用するタイミングを理解していますか?

はどちらも同様の用途を持っているように見えます:

class MyClass a b where 
    f :: a -> b -> Bool 

instance MyClass String String where 
    f s1 s2 = ... 

instance MyClass Int Int where 
    f i1 i2 = ... 

data Gadt a where 
    F :: String -> String -> Bool 
    F2 :: Int -> Int -> Bool 

はこれまでのところ、私は本当に見唯一の違いは、GADTのは、柔軟な数の引数を持つように関数型インターフェースを有効にすることである:

data Gadt a where 
    PassTwoArgs :: String -> String -> Gadt Bool 
    PassOneArgs :: String -> Gadt Bool 

myFunction :: Gadt a -> a 
myFunction (PassTwoArgs s1 s2) = ... 
myFunction (PassOneArgs s1) = ... 

ながら、これは型クラスでは簡単にはできません。

他の相違点や使用例がありますか?

答えて

6

クラスの場合は、いつでも新しいインスタンスを追加できます。

GADTを使用する場合は、永久に固定されたデータ構造があります。オリジナルの定義を変更することなく、新しいケースを決して追加することはできません。しかし、注意するように、はるかに柔軟性があります。

本当に、それらはさまざまなユースケースを対象としています。クラスは、他の方法とは何の関係もない、さまざまな種類のデータを処理できるようにしたいときに使用します。たとえば、IntStringにある(==)を実行できますが、これらのタイプはそれほど似ていません。の1つのタイプをにしたい場合はGADTを使用しますが、タイプパラメータの一部には何か説明があります。標準的な例は、GADTがあるプログラミング言語の式を表すところであり、Haskellタイプのシステムを使用して他の言語のタイプのシステムを強制したい場合です。

でないクラスは、のように、オブジェクト指向プログラミングで使用する「クラス」です。 ;-)そのようなアイデアをすべてあなたの脳の中に入れてください。

2

パターンマッチングが必要な場合は、(G)ADTを使用します。第三者がインターフェイスを実装できるようにするには、typeclassを使用します。

私の直感はできるだけ型抜きを使うことです。パターンマッチングが絶対に必要な場合は、(G)ADTに到達します。私は通常それを必要としません。

関連する問題