Search code examples
haskellmonadstypeclassstate-monad

Exporting a polymorphic MonadState function for a particular state data type


What I'm trying to do is (in a module I'm writing) export a function that works on a particular type in a state monad (in the example below, that type would be Foo). However I would like the user to be able to use the function in whatever MonadState type they wish: State.Lazy, State.Strict, StateT, etc. So it needs to be polymorphic in its outer state monad.

Here is an example of what I'd like to do:

EDITED with a better question:

import Control.Monad.State

data Foo a = Foo { cnt :: Int, val :: a }

--test :: State (Foo a) a           --  THIS WORKS
--test :: StateT (Foo a) Maybe a    --  ...SO DOES THIS
--  ... BUT INCLUDING THE FOLLOWING SIGNATURE GIVES AN ERROR:
test :: MonadState (Foo a) m => m a
test = modify (\(Foo i a)-> Foo (i+1) a) >> gets val

GHC complains that FlexibleInstances extension is required to define the type above. Is using that extension the correct way to define my function or is there a better way?

Thanks


Solution

  • Can't you just use the MonadState typeclass?

    {-# LANGUAGE FlexibleContexts #-}
    import Control.Monad.State
    
    data Foo a = Foo { cnt :: Int, val :: a }
    
    
    test :: MonadState (Foo a) m => m a
    test = modify (\(Foo i a)-> Foo (i+1) a) >> gets val
    

    It loads fine in GHCi.

    EDIT: This is with MTL-2.0 and GHCi-7.0.1