试图弄清楚Haskell类型类.以下为什么不工作?
{-# LANGUAGE FlexibleInstances #-}
class IntClass t
instance IntClass Int
intToIntClass :: (IntClass r) => Int -> r
intToIntClass x = x
Run Code Online (Sandbox Code Playgroud)
显然,"实例"并不意味着我认为它应该意味着什么.相反,它给出了错误消息,我不明白.
Could not deduce (r ~ Int)
from the context (IntClass r)
bound by the type signature for intToIntClass :: IntClass r => Int -> r
at f.hs:10:1-16
`r' is a rigid type variable bound by
the type signature for intToIntClass :: IntClass r => Int -> r
at f.hs:10:1
In the expression: x
In an equation for `intToIntClass t': intToIntClass x = x
Run Code Online (Sandbox Code Playgroud)
Dan*_*her 14
签名
intToIntClass :: (IntClass r) => Int -> r
Run Code Online (Sandbox Code Playgroud)
意味着intToIntClass可以产生调用者想要的任何类型的值,只要该类型属于IntClass.但实施只能产生Int价值.
Int到目前为止,这是唯一的实例没有帮助,就编译器而言,可能在其他模块中定义了更多实例,因此编译器不能接受仅生成Ints 的方法.
你写的这个函数说:"给我一些东西,我会把它还给你." 你写的类型说:"我可以转换Int为调用者想要的任何类型,只要该类型是IntClass类型类的实例."
当我们将它们组合在一起时,我们有一个函数可以Int从调用者那里获取,并直接返回.除非Int返回相同的内容,否则只要该类型是IntClass类型类的成员,它就是调用者想要的任何类型的值.如何将输入Int变为呼叫者想要的任何(约束)类型?它不能.由于输入是直接返回的,因此返回类型必须与参数类型相同.类型检查器从您的代码中推断出这一点,但是无法在命名输出类型时协调该推断r.类型检查器希望与您合作,但不能确定r与作为类型类的实例Int的唯一假设r是相同的IntClass.
fromInteger在Num类型类中找到一个与你编写的函数相似的函数.如果你想谈论你可以基于Inta 构建的所有类型,那么这应该是你的类型类的方法.就像是:
class IntClass a where
intToIntClass :: Int -> a
Run Code Online (Sandbox Code Playgroud)
您可以为要成为其实例的每种类型定义此方法IntClass,并且具有所需的类型intToIntClass :: IntClass r => Int -> r.这种返回类型多态性关键取决于具有适当定义的每个参与类型intToIntClass.