2012-07-16 5 views
8

ここでは、初心者の方が苦労しています。Haskell:セットの型クラスを定義するにはどうしたらいいですか?

私はセットの型クラスを定義しようとしています。この場合、「存在する」という定義だけが必要です。 'exists'は設定された項目に対してセットと機能を行い、ブール値は を返します。ハスケルでどのように定義できますか?

正しい方向にも以下のことがありますか?クラスのためにあまりにも多くのパラメータ `設定します。結果は(

- だから、

-- Set.hs -- 

class Set a b where 

    exists :: a -> (b -> Bool) -> Bool 


-- ListSet.hs -- 

instance Set ListSet a where 

    exists a f = True 

..「存在」がために型クラスの定義とリストとセットの 実装は、今のところはtrueを返すあり')

答えて

13

十分な拡張子を付けて、これを行うことができます。少なくとも、複数パラメータの型クラスが必要です。しかし、使用するのは非常に面倒です。あなたはどこにでも明示的な型署名を指定する必要があります。あまりにも、

class Set a b | a -> b where 
    exists :: a -> (b -> Bool) -> Bool 

これは、あなたがセットの種類を知っていれば、あなたは要素の種類を知っていると言う:それを修正する一つの方法は、(他の拡張子を使用して)機能的依存関係を導入することです。しかし、任意の拡張子なしで動作する簡単な方法があります:

class Set f where 
    exists :: f a -> (a -> Bool) -> Bool 

ここで、型クラスは、高kinded種類以上の範囲、あなたは決してきていない場合は、独自に思い付くために巧妙なトリックとハードであります前にそれを見た!

+1

もちろん、後者の場合は、要素型をセット型の最後の型パラメータにする必要があります。これは 'a - > Bool'のインスタンスを作成する場合のように、必ずしも可能ではありません。一方、関連タイプのファミリーは、それだけで問題は解決します。 – Carl

+2

ありがとう!私は二番目の方法が働いている!私はそこに何が起こっているのか分かりませんが、うまくいけばそれは私には明らかです... – tero

7

ダニエル・ワグナーは、あなたがしようとしていることについてすでに完全な答えを出していました。あなたのエラーについての点を追加したいだけです - Too many parameters for class 'Set'。これは、対応するGHC拡張 - MultiParamTypeClassesを有効にしなかったことを意味します。ソースファイルの一番上に特別な種類のコメントを指定することで可能です:

{-# LANGUAGE MultiParamTypeClasses #-} 
-- 
-- Your source code here 
-- 

コードをコンパイルできるはずです。

ダニエルの回答で言及されているもう1つのHaskellの機能では、特定の拡張子、つまりFunctionalDependencies(これは奇妙な.. | a -> b ..の内部型クラス宣言)を有効にする必要があります。あなたはこのように、カンマを使用して同時に複数の拡張機能を有効にすることができます。

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 

カールさんのコメントも、何をしようとするための手段を提供することができ、別の拡張子、TypeFamilies、(一般的なセットタイプのクラスまたは他の言及しますコレクションの種類)。あなたはそれについてここで読むことができます:http://www.haskell.org/haskellwiki/Type_families

+0

私はそれを機能依存方法でもやっていました。しかし、私はまた、 'FlexibleInstances'拡張を含める必要がありました。 – tero

関連する問題