我有这个不编译的代码.我想明白为什么它不能推断出类型.
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
Run Code Online (Sandbox Code Playgroud)
这是错误:
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’
Run Code Online (Sandbox Code Playgroud)
鉴于我理解正确,你定义了错误的签名getValue.现在定义:
class HasValue a where
getValue :: IntRun Code Online (Sandbox Code Playgroud)
所以这意味着可以有不同的版本getValue,但由于这些都返回了Int,所以我们完全不可能知道instance我们想要选择哪个版本.
根据instance文件后面的声明(以及函数的名称),我认为你实际上在寻找:
class HasValue a where
getValue :: a -> IntRun Code Online (Sandbox Code Playgroud)
现在Haskell可以a从函数应用程序的参数类型派生出来.此外,这也与你的功能体相匹配instance HasValue.
此外,Combiner它不是一个单型,所以我们需要在头部添加类型参数:
instance HasValue (Combiner a) where
getValue (Combiner x f) = f xRun Code Online (Sandbox Code Playgroud)