无法将类型`h'与`String'匹配

时间:2017-11-03 00:31:50

标签: haskell functional-programming

我是从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,我很乐意尝试它!。

1 个答案:

答案 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
    ...

每个都需要一些扩展,我认为错误消息将引领方向。