2010-12-02 33 views
0

Ce que j'essaie de faire est (dans un module que j'écris) exporter une fonction qui fonctionne sur un type particulier dans une monade d'état (dans l'exemple ci-dessous, ce type serait Foo). Cependant, je voudrais que l'utilisateur puisse utiliser la fonction dans n'importe quel type MonadState qu'ils souhaitent: State.Lazy, State.Strict, StateT, etc. Il doit donc être polymorphe dans son état externe monad.Exportation d'une fonction MonadState polymorphe pour un type de données d'état particulier

Voici un exemple de ce que je voudrais faire:

ÉDITÉ une meilleure 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 se plaint que l'extension FlexibleInstances est nécessaire pour définir le type ci-dessus. Est-ce que l'utilisation de cette extension est la bonne façon de définir ma fonction ou existe-t-il un meilleur moyen?

Merci

+0

Quelque chose comme cela devrait probablement travailler - Je crains que je ne peux pas le tester au moment (et ça devient non formaté): [_ test :: MonadState (Foo a) m => ma _] –

Répondre

2

Tu ne peux pas utiliser la classe de types MonadState?

{-# 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 

Il charge bien dans GHCi.

EDIT: Ceci est avec MTL-2.0 et GHCi-7.0.1

+0

J'aurais dû inclure la signature de type que vous avez fournie dans mon article original, mais elle a été omise. Édité. Je suppose que ma vraie question est alors de savoir si ce drapeau FlexibleContexts est le bon (ou le seul) moyen de le faire. – jberryman

+2

Oui, je crois que FlexibleContexts est nécessaire. Il a été proposé à Haskell Prime et je parie que d'autres compilateurs Haskell le soutiendront (jhc, uhc), donc je n'essaierai pas trop de l'éviter. –