我想访问实例中的类型变量,这些变量不会显示在实例的参数中。例如,
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.
答案 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