我从 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 进行建模,我很乐意尝试!
最佳答案
这个
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
...
每个扩展都需要一些扩展,我认为错误消息会引导我们。
关于haskell - 无法将类型 `h' 与 `String' 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47086704/