为什么不能在此实例声明中使用类型变量?

时间:2018-09-10 11:43:33

标签: haskell

我正在尝试使用TypeApplications来消除我正在调用的类型类实例之间的歧义。不幸的是,似乎实例声明的类型参数不能在实例主体中使用。具体来说,在这个玩具示例中:

{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE TypeApplications     #-}
{-# LANGUAGE UndecidableInstances #-}

class Foo a where
    foo :: String

instance Foo () where
    foo = "()"

instance Foo Int where
    foo = "Int"

class Bar b where
    bar :: String

instance Foo a => Bar a where
    bar = foo @a

将在最后一行出现Not in scope: type variable 'a'错误。如果删除类型应用程序,则会给出错误Could not deduce (Foo a0) from the context Foo a,这是合理的,因为驴foo本身是模棱两可的。

我是否可以通过某种方式访问​​类型参数,或者以其他方式强迫编译器识别此参数?

1 个答案:

答案 0 :(得分:7)

类型变量可以在实例声明中使用,但前提是它是作用域

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE TypeApplications, AllowAmbiguousTypes   #-}
{-# LANGUAGE ScopedTypeVariables, UnicodeSyntax      #-}

class Foo a where foo :: String

class Bar b where bar :: String

instance ∀ a . Foo a => Bar a where
  bar = foo @a

和往常一样,如果您更喜欢ASCII,也可以将写入forall