forcing a type constraint on data

Hi all, I would like to make a more restrictive version of a certain datatype. I tried wrapping it in a newtype, fundeps, type families, really got lost :) What I'm trying to achieve is the following: The original package http://hackage.haskell.org/packages/archive/reaction-logic/2010.11.17/doc/ht... has a constructor function (mkReactor) with exactly the constraints I'm after. However, the constraint is just on this constructor function, not on the data itself. All functions I write are inferred as "Reactor (State s) c", while the use of that constructor ensures that s == c. Also, I might switch "State s" for some "StateT s m" later on, so I would really like to be able to use "(MonadState c m) => Reactor m c" in my functions as well, since this is the most generic. Trying that blows up however: Could not deduce (m ~ StateT s Identity) from the context (ValidEvent event, MonadState s m) `m' is a rigid type variable bound by the type signature for `stepper2' at Eventer.hs:77:45 In the first argument of `runState', namely `(insertExternals reactor [Serial event])' In the expression: runState (insertExternals reactor [Serial event]) state In an equation for `stepper2': stepper2 (Just reactor, state) event = runState (insertExternals reactor [Serial event]) state Can someone please explain the cause of this problem? Are there workarounds? Language extensions? Thanks in advance, Mathijs

On Sun, Jan 2, 2011 at 01:37, Mathijs Kwik
The original package http://hackage.haskell.org/packages/archive/reaction-logic/2010.11.17/doc/ht... has a constructor function (mkReactor) with exactly the constraints I'm after. However, the constraint is just on this constructor function, not on the data itself. All functions I write are inferred as "Reactor (State s) c", while the use of that constructor ensures that s == c.
The haskell98 way to do this, is to restate the constraints in every function where you use your data type. So every function that uses a "Reactor m c" and needs the fact that it has a "MonadState c m", needs this in its context: "MonadState c m => Reactor m c -> ..." Using the GADTs language extension, you can create a constructor that contains the proof that the type contained is a member of a certain type class. For example: data HasShow a where HasShow :: (Show a) => a -> HasShow a newShow :: HasShow a -> String newShow (HasShow x) = show x Note that newShow doesn't need a "Show a" constraint. Erik
participants (2)
-
Erik Hesselink
-
Mathijs Kwik