我想在多态性类型的参数和返回类型中定义一组功能,就像下面一样。
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
声明?
更改poly
的类型?现在,没有什么能让您(或某些随机库(添加例如添加Poly Double Int
实例,这就是poly 3
中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。