2017-06-30 121 views
2

如果我想在問題空間上執行搜索並且想跟蹤節點已經訪問過的不同狀態,我需要several options to do it depending on the constraints of those states。然而;有沒有一種方法可以根據用戶用作輸入的狀態約束來調度函數或另一個函數?舉例來說,如果我有:在函數中檢查Haskell類型類

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

,我想在Problem a執行搜索,是有辦法,我可以檢查是否aEqOrdHashable,然後調用不同的搜索?在僞代碼,類似:

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 

我知道我可以讓用戶選擇一個search或其他根據自己的使用;但能夠做這樣的事情對我來說可能非常方便,因爲搜索並不是真正的用戶端點之一(例如,可能是一個函數bfs,它調用search並帶有一些參數以使其表現得像廣度優先搜索)。

+0

所有類型信息在編譯過程中都被擦除:在運行時,值不會在內存中與其類型標記在一起,也不存在所有類型類實例的表示。這使得這種檢查不可能。如果需要這些信息,則程序員必須明確要求保留它,例如,像丹尼爾瓦格納下面的習慣課程一樣。 – 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

我不知道如果我得到它:我仍然不知道如何執行'Memorable'類作爲'Eq a',這可以讓我概括它。就像'實例令人難忘(公式a => a)哪裏可能? –

+0

@DiegoVicente如果可能的話,你不需要'Memorable'類型的類。 'Eq'根本沒有足夠的信息來執行你想要的檢查。 – chi

+0

@DiegoVicente不,這是不可能的(當然,但是你不能有任何其他的實例)。你必須編寫例如'Instability Memorable Int where type Int Int = EqMemory Int;記住= eqRemember;已知= eqKnown',如果你想'Int'使用'Eq'實例來存儲它的內存。是的,這意味着你必須複製'Ord','Hashable'和'Eq'已存在的所有實例聲明 - 這就是爲什麼大多數人只需選擇Ord或Hashable就可以運行它。 –