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



我想在多态性类型的参数和返回类型中定义一组功能,就像下面一样。

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 33的类型。

你可以做

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。

最新更新