Haskell 哈斯克尔无法从上下文中推断

Haskell 哈斯克尔无法从上下文中推断,haskell,Haskell,我有一段代码没有编译。我想知道为什么它不能推断出这些类型 module Main where data Combiner a = Combiner a (a -> Int) comb = Combiner 3 (\x -> 5) class HasValue a where getValue :: Int instance HasValue Combiner where getValue (Combiner x f) = f x main = print $ getV

我有一段代码没有编译。我想知道为什么它不能推断出这些类型

module Main where

data Combiner a = Combiner a (a -> Int)
comb = Combiner 3 (\x -> 5)

class HasValue a where
  getValue :: Int

instance HasValue Combiner where
  getValue (Combiner x f) = f x

main = print $ getValue comb
以下是错误:

main.hs:8:3: error:
• Could not deduce (HasValue a0)
  from the context: HasValue a
    bound by the type signature for:
               getValue :: HasValue a => Int
    at main.hs:8:3-17
  The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘getValue’
  To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
  When checking the class method:
    getValue :: forall a. HasValue a => Int
  In the class declaration for ‘HasValue’

如果我理解正确,您为
getValue
定义了错误的签名。现在定义如下:

class HasValue a where
  getValue :: Int
现在Haskell可以从函数应用程序的参数类型导出
a
。此外,这还与
实例HasValue
中的函数体相匹配

此外,
组合器
不是单一类型,因此我们需要在头部添加类型参数:

instance HasValue (Combiner a) where
  getValue (Combiner x f) = f x
实例HasValue(组合器a),其中

getValue(组合器xf)=fx
的签名不应该是
getValue
a->Int
?这可能不是唯一的错误。有时候从第一个开始是有意义的,不过还有另一个问题。
HasValue
实例应该是
实例HasValue(组合器a)
,而不仅仅是
实例HasValue组合器
。谢谢。还有,所有带有*种类的类型都是完全固定的吗?@PetrasPurlys:经过重新阅读,我认为术语monotype更合适,是的,这些类型带有种类
*
instance HasValue (Combiner a) where
  getValue (Combiner x f) = f x