[英]Haskell: How can I set polymorphic types of arguments and return types
I want to define a set of functions in polymorphic type of arguments and return types, just as below. 我想在参数的多态类型和返回类型中定义一组函数,如下所示。
class Poly a b where
poly :: a -> b
instance Poly Int Int where
poly :: Int -> Int
poly a = a
When I test it in ghci, using poly 3 :: Int
and then it gives me errors: 当我在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
When I use poly (3 :: Int) :: Int
, it returns me the right value 3
... I would like to know how to get rid of the tedious :: Int
declaration? 当我使用poly (3 :: Int) :: Int
,它为我返回正确的值3
...我想知道如何摆脱乏味的:: Int
声明?
Change the type of poly
? 更改poly
类型? Right now nothing keeps you (or some random library) from adding eg a Poly Double Int
instance, which is why the type of 3
in poly 3
is ambiguous. 现在,没有什么可以阻止您(或某些随机库)添加例如Poly Double Int
实例,这就是为什么poly 3
中3
的类型不明确的原因。
You could do 你可以做
instance Poly a where
poly :: a -> a
That would nail down the type of poly 3 :: Int
, but it would make poly
less general. 这样可以确定poly 3 :: Int
的类型,但会使poly
不那么通用。
You could enable FunctionalDependencies
and do 您可以启用FunctionalDependencies
并执行
instance Poly a b | b -> a where
poly :: a -> b
Then poly 3 :: Int
would be OK, because b
is declared as uniquely determining a
. 那么poly 3 :: Int
就可以了,因为b
被声明为唯一确定a
。
You could also enable TypeFamilies
and use an associated type: 您还可以启用TypeFamilies
并使用关联的类型:
class Poly b where
type Arg b :: *
poly :: Arg b -> b
instance Poly Int where
type Arg Int = Int
poly x = x
Again, this lets ghc derive the argument type from the result type, so poly 3 :: Int
typechecks. 再次,这使ghc从结果类型派生参数类型,因此, poly 3 :: Int
类型检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.