On Fri, Mar 4, 2011 at 3:45 PM, Yves Parès <limestrael@gmail.com> wrote:
Hello,

For testing purposes, I am trying to make an overlay to IO which carries a phantom type to ensure a context.
I define contexts using empty type classes :

class CtxFoo c
class CtxBar c

The overlay :

newtype MyIO c a = MyIO (IO a)

Then I define some methods that run only a specific context :

runFoo :: (CtxFoo c) => MyIO c a -> IO a
runFoo (MyIO x) = x

runBar :: (CtxBar c) => MyIO c a -> IO a
runBar (MyIO x) = x

And then an action that runs in context 'Foo' :

someAction :: (CtxFoo c) => MyIO c ()
someAction = putStrLn "FOO"

Then I run it :

main = runFoo someAction

But obiously, GHC complains that my type 'c' remains uninstantiated :

    Ambiguous type variable `c' in the constraint:
      (CtxFoo c) arising from a use of `runFoo'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: runFoo someAction
    In an equation for `main': main = runFoo someAction


Is there a way to deal with this ?
The interest of using type classes and not empty types to represent the contexts is that it stays simple, and that I can do that :

someAction2 :: (CtxFoo c, CtxBar c) => MyIO c ()
someAction2 = putStrLn "FOO and BAR"

... a function that can run in both contexts.


data X
instance CtxFoo X

runFoo (someAction :: MyIO X ())

data Y
instance CtxFoo Y
instance CtxBar Y

runFoo (someAction2 :: MyIO Y ())
runBar (someAction2 :: MyIO Y ())

runFoo (someAction :: MyIO Y ()) -- also works since Y provides both a Foo and Bar context)

  -- ryan

 
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe