haskell - 可以从实例函数声明中访问类型变量吗?

时间:2011-09-11 23:59:29

标签: haskell instance typeclass

我想访问实例中的类型变量,这些变量不会显示在实例的参数中。例如,

class A a where foo :: a b
data C a
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

当然,上面的内容将在没有范围类型表达式的情况下解析,但我有一个非玩具示例,我实际上想要它。

修改

在粘贴之前请尝试您的代码作为答案!以上(丹尼尔的答案)导致

Test.hs:51:5: Misplaced type signature: foo :: forall b. C b
Failed, modules loaded: none.

4 个答案:

答案 0 :(得分:3)

我认为要克服Daniel解决方案的问题,即不允许为类型类函数提供签名,您只需定义顶级函数并在类型类的实例中“重命名”它。在您的简单示例中,以下内容应该有效。

{-# LANGUAGE ScopedTypeVariables #-}

class A a where 
    foo :: a b

instance A C where
    foo = foo'

foo' :: C b
foo' = undefined :: C b

答案 1 :(得分:2)

虽然真正的解决方案更可取,但可以使用asTypeOf解决问题并添加虚拟参数。这是一个例子,

class A a where foo2 :: b -> a b -- added parameter b
data C a
instance A C where
    foo2 x = undefined `asTypeOf` (wrapA x)

wrapA :: A C => a -> C a
wrapA = undefined

foo :: A a => a b
foo = foo2 undefined

这恰好适合我的现实世界的例子。干杯!

答案 2 :(得分:1)

我认为在课堂宣言中

class A a where
    foo :: a b

foo的类型确实是

forall b. a b

foo应该与b类型无关。或者,b实际上并不是班级A的一部分。那么......我认为你不应该能够参考它吗?虽然我可能不理解......也许你可以发布一个必要的例子吗?

如果需要在多个方法中保持相同的类型,可以使用多参数类型类:

class A a b where
    foo :: a b
    bar :: a b

答案 3 :(得分:0)

{-# LANGUAGE ScopedTypeVariables #-}
class A a where foo :: a b
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

Read more.