开发者

haskell -- can one access type variables from an instance function declaration?

I want to access type variables in an instance, that don't show up in the instance's parameters. For example,

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

Of course, the above will resolve without the scoped type expression, but I have a non-toy example where I actually want it.

edit

please try your code before pasting it as an answer! The a开发者_如何学Cbove (Daniel's answer) results in

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


I think to overcome the problem with Daniel's solution that you are not allowed to provide a signature for a type class function you can simply define a top-level function and "rename" it in the instance of the type class. In your simple example the following should work.

{-# LANGUAGE ScopedTypeVariables #-}

class A a where 
    foo :: a b

instance A C where
    foo = foo'

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


While a real solution would be preferable, one can work around the problem using asTypeOf, and adding dummy parameters. Here's an example,

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

That happened to work for my real-world example. cheers!


I think in the class declaration

class A a where
    foo :: a b

the type of foo is really

forall b. a b

ie foo should be sort of independent of the type b. Or, b is not actually part of the class A. So... I don't think you should need to be able to refer to it? Though I might not be understanding... maybe you could post an example where it is necessary?

If you need to keep the same type across more than one method you could use a multi-parameter type class:

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


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

Read more.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜