2017-06-30 13 views
2

問題空間で検索を実行したい場合、ノードが既に訪れたさまざまな状態を追跡したい場合、I several options to do it depending on the constraints of those states。しかしながら;ユーザーが入力として使用している状態の制約に応じて関数やその他をディスパッチする方法はありますか?例えば、私が持っていた場合:関数内のHaskell型式メーターのチェック

data Node a = Node { state :: a, cost :: Double } 

そして、私はProblem a上で検索を実行したい、aEqOrdまたはHashableあり、その後、検索の異なる種類を呼び出す場合、私がチェックできる方法はありますか?擬似コードでは、何かのように:

search :: Eq a => Problem a -> Node a 
search [email protected](... initial ...) -- Where initial is a State of type a 
    | (Hashable initial) = searchHash problem 
    | (Ord initial)  = searchOrd problem 
    | otherwise   = searchEq problem 

私はちょうど、ユーザーが自分の用途に応じて1 searchまたは別を選択してみましょう可能性が承知しています。そのようなことをすることができるのは、検索が実際にはユーザーエンドポイントの1つではないためです(1つの例は、bfsであり、searchをコールして、それがBreadth-Firstサーチ)。

+0

コンパイル時に、すべてのタイプ情報が消去されます。実行時に、値はタイプでメモリにタグ付けされず、すべてのタイプクラスインスタンスの表現もありません。これはそのようなチェックを不可能にする。この情報が必要な場合、プログラマは明示的にそれを保持するように要求しなければならない。 Daniel Wagnerのようにカスタムクラスで以下のようにします。 – chi

答えて

2

いいえ、できません。ただし、独自のクラスを作ることができます:

class Memorable a where 
    type Memory a 
    remember :: a -> Memory a -> Memory a 
    known :: a -> Memory a -> Bool 

は、例えば、いくつかの基本型のため、このクラスをインスタンス化し、新しいインスタンスを追加したい人々のためのいくつかのデフォルトの実装を追加します

-- suitable implementations of Memorable methods and type families for hashable things 
type HashMemory = Data.HashSet.HashSet 
hashRemember = Data.HashSet.insert 
hashKnown = Data.HashSet.member 

-- suitable implementations for orderable things 
type OrdMemory = Data.Set.Set 
ordRemember = Data.Set.insert 
ordKnown = Data.Set.member 

-- suitable implementations for merely equatable things 
type EqMemory = Prelude.[] 
eqRemember = (Prelude.:) 
eqKnown = Prelude.elem 
+0

私はそれを得るかどうか分かりません:私はまだ 'Eq a'というものの' Memorable'クラスを実装する方法を知らないので、一般化することができます。 'Memorable(Eq a => a)インスタンスが可能なところ? –

+0

@DiegoVicente可能ならば、 'Memorable'型クラスは必要ありません。 'Eq'はあなたが望むチェックを実行するのに十分な情報を伝えません。 – chi

+0

@DiegoVicenteいいえ、それは可能ではありません(そうですが、あなたは他のインスタンスを持つことはできません)。あなたは例えばを書かなければなりません。 'インスタンスMemory Int = EqMemory Int型のMemorable Int;覚えて= eqRemember; 'Int'がそのメモリに' Eq'インスタンスを使用するようにしたい場合は、 'known = eqKnown'となります。はい、これは、 'Ord'、' Hashable'、 'Eq'のために既に存在するインスタンス宣言をすべて複製する必要があることを意味します。これはほとんどの人が' Ord'または 'Hashable'を選択して実行する理由です。 –

関連する問題