2017-06-30 92 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就可以运行它。 –