我想在多态类型的参数和返回类型中定义一组函数,如下所示。
class Poly a b where
poly :: a -> b
instance Poly Int Int where
poly :: Int -> Int
poly a = a
当我在ghci中测试它时,使用poly 3 :: Int
然后它会给我错误:
*Poly> poly 3 :: Int
<interactive>:486:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘poly’
prevents the constraint ‘(Poly a0 Int)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
instance Poly Int Int
-- Defined at OneFunctionManyArguments.hs:10:10
• In the expression: poly 3 :: Int
In an equation for ‘it’: it = poly 3 :: Int
<interactive>:486:6: error:
• Ambiguous type variable ‘a0’ arising from the literal ‘3’
prevents the constraint ‘(Num a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...plus two others
...plus 46 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘poly’, namely ‘3’
In the expression: poly 3 :: Int
In an equation for ‘it’: it = poly 3 :: Int
当我使用poly (3 :: Int) :: Int
时,它会返回正确的值3
...
我想知道如何摆脱繁琐的:: Int
声明?
答案 0 :(得分:5)
更改poly
的类型?现在没有什么能阻止你(或一些随机库)添加例如Poly Double Int
实例,这就是3
中poly 3
的类型不明确的原因。
你可以做到
instance Poly a where
poly :: a -> a
这会确定poly 3 :: Int
的类型,但会使poly
不那么笼统。
您可以启用FunctionalDependencies
并执行
instance Poly a b | b -> a where
poly :: a -> b
然后poly 3 :: Int
就行了,因为b
被声明为唯一确定a
。
您还可以启用TypeFamilies
并使用关联的类型:
class Poly b where
type Arg b :: *
poly :: Arg b -> b
instance Poly Int where
type Arg Int = Int
poly x = x
同样,这允许ghc从结果类型派生参数类型,因此poly 3 :: Int
typechecks。