Search code examples
haskellpolymorphismalgebraic-data-types

How to store a polymorphic function in a data type


I have a data type in which I would like to store a function: State Foo a -> a. Presumably, when an instance of this type is created the program will partially apply evalState with the initial state for the computation and store the resulting function in the data structure. Later, the function could be retrieved from the instance and used to evaluate one or more computations within the State monad and get the result.

-- This doesn't work
data Bar = Bar {
  -- other members here
  runWithState :: State Foo a -> a
}

==> Not in scope: type variable 'a'

I cannot make a more concrete because I do not know what the end result of the computation will be, and it could change depending on what computation produces.

How do I make the type checker work with this?


Solution

  • Use forall with the RankNTypes extension:

    {-# LANGUAGE RankNTypes #-}
    
    import Control.Monad.State
    
    type Foo = String
    
    data Bar = Bar {
       -- other members here
       runWithState :: forall a. State Foo a -> a
    }