2011-04-12 2 views
0

J'ai récemment généralisé une classe de type à partir d'une contrainte MonadError GenError m à une contrainte plus flexible de MonadError e m, CanContainGenError e. Ceci est utile pour utiliser le transformateur monad correspondant avec une pile qui a déjà un ErrorT SomeError m - Je peux simplement ajouter GenError en tant qu'élément d'un nouveau constructeur dans le type de données SomeError.Y a-t-il une classe "ContainsType"?

Je me suis surpris à écrire une classe personnalisée CanContainGenError codée en dur à GenError. N'y at-il pas une classe commune ContainedType ou une telle? (Je l'ai presque appelé "sous-type", heh)

Quelque chose comme le ci-dessous CanContainType ou ContainsType classes que je viens de faire?

class CanContainType cont orig where 
    toCont :: orig -> cont 
    fromCont :: cont -> Maybe orig 

class ContainsType orig sub where 
    toContainer :: orig -> cont 
    fromContainer :: cont -> orig 

Lorsqu'un exemple instanciation est:

-- edit fixed example instance to reflect what I want, sorry for the misleading code 
data IntOrFloatOrDouble= I Int | F Float | D Double 
instance CanContainType IntOrFloatOrDouble Int where 
    toCont = I 
    fromCont (I a) = Just a 
    fromCont _ = Nothing 

Maintenant que je l'ai tapé ceci je me rends compte il n'y a probablement pas établi un parce que mes exigences mandat MPTCs. Pourtant, je suis intéressé par toutes les pensées.

+0

Votre 'toCont' pour IntAndStuff ne fonctionne pas. Ce qui montre aussi pourquoi vos fonctions 'toCont' et' toContainer' sont un peu mal typées, je pense. Si vous injectez une valeur dans un conteneur, vous avez besoin de valeurs par défaut pour tous les autres bits. D'une manière générale, je pense que cette solution est un peu trop étroite entre les deux, de sorte que les personnes qui en veulent/en ont besoin passent souvent à des solutions basées sur HList. – sclv

+0

@sclv À droite, cette instance était mal pensée. Dans mon vrai code j'ai 'data SomeError = PreExistinErr1 | PreExistinErr2 | IsGenError GenError' et dans l'instance c'est juste 'toCont = IsGenError'. C'est pourquoi je n'ai pas besoin de bits par défaut. Voir ma modification. –

Répondre

1

Parfois, des choses de ce genre apparaissent dans la construction EDSL, pour lever des instances de Haskell à l'EDSL. Voir par exemple http://www.galois.com/~dons/tmp/Type.hs

data IntegralType a where 
    TypeInt  :: IntegralDict Int  -> IntegralType Int 
    TypeInt8 :: IntegralDict Int8 -> IntegralType Int8 
    TypeInt16 :: IntegralDict Int16 -> IntegralType Int16 
    TypeInt32 :: IntegralDict Int32 -> IntegralType Int32 
    TypeInt64 :: IntegralDict Int64 -> IntegralType Int64 
    ... 

Il n'y a rien de standard, évidemment.

Questions connexes