简体   繁体   English

Haskell:如何设置参数的多态类型和返回类型

[英]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 33的类型不明确的原因。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM