2013-06-14 7 views
24

私はコードを使用するときや、typeclassを使わないときには理解するのが難しいです。私は自分自身を作成を意味し、は既に定義されていません使用もちろん、タイプメガネ。例(非常に愚かな例)で、私は実行する必要があります。私はtypeclassesを使うべきかどうか?

data Cars = Brakes | Wheels | Engine 
data Computers = Processor | RAM | HardDrive 

class Repairable a where 
    is_reparaible :: a -> Bool 

instance Repairable Cars where 
    is_repairable (Brakes) = True 
    is_repairable (Wheels) = False 
    is_repairable (Engine) = False 

instance Repairable Computers where 
    is_repairable (Processor) = False 
    is_repairable (RAM)  = False 
    is_repairable (HardDrive) = True 

checkState :: (Reparaible a) => a -> ... 
checkState a = ... 

(もちろん、これは愚かな、不完全な例です)。

しかし、これはちょっとした用途のためにたくさんあります。なぜ私は新しいデータ型と型式(インスタンスを持つ)を定義しなくても、何か単純で機能を定義するだけではいけません。

この例題はあまりにも単純ですが、関数を定義するだけではなくgithubでHaskellコードを参照すると、実際には(新しいデータ型+型式+インスタンス)のような事がよくあります。

私は新しいデータ型、型式などを作成する必要がありますが、いつ関数を使うべきですか?

ありがとうございました。

答えて

40

なぜ私は、単純な何かをするだけ(その インスタンスで)新しいデータ型と型クラスを定義せずに機能 を定義するべきではありません。

どうしてですか?

checkState :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b 
checkState is_repairable repairs destroy a 
    = if (is_repairable a) then repairs a else destroy a 

人は、常に誤使用タイプのクラスを定義することができます。それが慣用的であるということではありません。

  • が一つだけあります:場合

    利用型クラス:

    があなたのより一般的な質問に答えるために、ここでは型クラスを使用するときのために、それらを使用しないように親指のいくつかのルールがあります指定された型ごとに正しい行動

  • 型クラスが関連付けられた方程式のすべてのインスタンスが満たさなければならない(つまり、「法律」)

場合は型クラスを使用しないでください:あなたは、単に名前空間のものにしようとしている

  • 。これがモジュールと名前空間の目的です。

  • それはインスタンスのソースコードを見ずにどのように動作するかについて推論することはできませんあなたのタイプのクラスを使用している人は

  • あなたがオンにする必要があり拡張子が制御不能になっていることがわかり

+0

うん!これは非常に完全な答えです、ありがとうございます!あなたの "タイプクラスを使用しない場合は..."は、何かを行う良い方法を選択するのに特に役立ちます。 – vildric

+1

これは絶対に厳密な規則ではありませんが、一般的なヒントのように、「1つのメソッドのためだけに型抜きを使用しないでください」という追加になります。 – MathematicalOrchid

+2

@MathematicalOrchidこれは「ニーズの法則」ルールの一部です。これは、1つのメソッドしか持たない型クラスの法則を持つことはめったにありません(連想法を持つ 'SemiGroup'のようなものを除いて) –

5

タイプクラスの代わりにデータ型を使用することができます。もちろん

data Repairable a = Repairable 
    { getRepairable :: a 
    , isRepairable :: Bool 
    , canBeRepairedWith :: [Tool] -> Bool -- just to give an example of a function 
    } 

は、あなたが明示的にこの値を渡す必要がありますが、複数の選択肢を持っている場合、これは良いことをすることができ(例えばSumを考えると数字のための可能なMonoid SなどProduct)。あなたが多かれ少なかれ同じタイプのクラスと同じ表現力を持っていることを除けば。

+2

私はdownvoterではないが、。 。 。この回答は本当に質問IMHOに答えるものではありません。 OPは、いつ型式を使うべきかを尋ねている。この回答は、タイプメスの代わりに言及していますが、その代替方法をいつ使うべきかは言いません。 (何かがあれば、タイプメらが意味を成すときの理解を前提としているようであり、同じケースの多くで理にかなった選択肢を提供している)。 – ruakh

関連する問題