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

标签 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 进行建模,我很乐意尝试!

最佳答案

这个

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/

相关文章:

haskell - haskell 中的 "Open Data Types and Open Functions"

Haskell 文本包选择

clojure - 针对实际问题的命令式解决方案与功能式解决方案的好例子

c - C 中的函数式编程(柯里化(Currying))/类型问题

functional-programming - 为什么我们用箭头显示多个参数,并用箭头显示返回类型?

haskell - 'many' 类型类中的“some”和 'Alternative' 函数

haskell - 越界 `select` 即使我 `constrain` 索引

haskell - 如何区分具有不同幻像类型的GADT构造函数?

haskell - 我如何概括 Maybe 和 Either 的违约行为?

haskell - 处理 SomeException 被忽略