我是从Haskell开始的,我希望您对以下代码无效的原因有所了解。主要思想是做一个代表概率质量函数的类
--a encapsulates a set of hypotheses of type h
class Pmf a where
hypos :: a -> [h]
prob :: a -> h -> Double
probList :: a -> [(h,Double)]
probList a = map (\h->(h, prob a h)) $ hypos a
这个想法是一般的,所以我可以定义
data BoxSet = BoxSet { ids::[String], items::[(String,Int)]} deriving(Show)
并使BoxSet成为像
这样的实例instance Pmf BoxSet where
hypos = ids
prob cj _ = let one = 1
len = doubleLength $ ids cj in one/len
但这会产生以下错误
<interactive>:2:13: error:
* Couldn't match type `h' with `String'
`h' is a rigid type variable bound by
the type signature for:
hypos :: forall h. BoxSet -> [h]
at <interactive>:2:5
Expected type: BoxSet -> [h]
Actual type: BoxSet -> [String]
* In the expression: ids
In an equation for `hypos': hypos = ids
In the instance declaration for `Pmf BoxSet'
* Relevant bindings include hypos :: BoxSet -> [h] (bound at <interactive>:2:5)
可以将h作为附加类参数,但是将来我将使用新类型d扩展类以获取数据,我将this problem
那么,如果你能告诉我为什么String不能匹配为h,我将不胜感激,如何解决这个问题。我理解它期望任何类型的h,但在一个实例中,给h一个特定的类型是有意义的。
另外,我想我可能不会在这里充分发挥功能性思维。所以如果你能指出一个更好的方法来模拟这些Pmf,我很乐意尝试它!。
答案 0 :(得分:3)
此
class Pmf a where
hypos :: a -> [h]
prob :: a -> h -> Double
是
的缩写class Pmf a where
hypos :: forall h. a -> [h]
prob :: forall h. a -> h -> Double
也就是说,两个签名中的h
是不相关的,而且这些函数中的每一个都需要适用于调用者可能选择的任何h
。我认为你正在寻找任何一种类型的家庭
class Pmf a where
type Hypothesis a :: *
hypos :: a -> [Hypothesis a]
...
instance Pmf BoxSet where
type Hypothesis BoxSet = String
...
或功能依赖,它们做同样的事情,但有不同的招摇
class Pmf a h | a -> h where
hypos :: a -> [h]
...
instance Pmf BoxSet String where
...
每个都需要一些扩展,我认为错误消息将引领方向。