On Fri, Mar 4, 2011 at 3:45 PM, Yves Parès <[email protected]> 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 > [email protected] > http://www.haskell.org/mailman/listinfo/haskell-cafe > >
_______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
