2017-02-14 8 views
1

J'ai une famille de type IfEq (n :: Nat) (m :: Nat) o qui évalue à o ou Void en fonction de n :== m. Puisque Maybe Void est seulement inibited par Nothing je devrais être capable de définir une fonction Maybe (IfEq n m o) -> Maybe o mais je ne peux pas comprendre dehors.Convaincre GHC que `Peut-être Void` est un type d'unité

Suivi: Cela peut-il être généralisé de la monade Maybe à un type plus général? (par exemple tous. MonadPlus s)

EDIT: J'avais d'abord roulé ma propre Nat mais (merci à ce @chi) avec le GHC Nat genre KnownNat constrait il assez simple de faire ce que je décris ci-dessus. Cependant GHC ne peut pas déduire KnownNat a => KnownNat (1+a) qui est impératif pour moi donc je suis de retour à la case 1.

+0

Vous ne pouvez pas définir une telle fonction (bien, vous pouvez simplement avoir 'juste x = erreur .. »mais je suppose que vous cherchez un moyen sûr de le faire) parce que vous ne pouvez pas faire correspondre un modèle. Au moins, vous auriez besoin de 'Typeable (IfEq n m o) => Peut-être (IfEq n m o) -> Peut-être o'. La stratégie générale consiste à utiliser des singletons. – user2407038

Répondre

2

Essayez quelque chose comme

foo :: forall n m o . (KnownNat n, KnownNat m) => 
     IfEq n m o -> Maybe o 
foo x = case sameNat (Proxy :: Proxy n) (Proxy :: Proxy m) of 
    Just Refl -> Just x 
    Nothing -> Nothing 
+0

Je ne pensais pas que c'était important mais j'avais roulé mes propres données Nat = Suc Nat | Zéro'. Est-il possible d'inférer 'KnownNat a => KnownNat (1 + a)'? – fakedrake

+0

@fakedrake Je pense que votre problème actuel est que, lors de l'exécution, les natals 'n, m' de niveau type ne sont pas stockés en mémoire, donc nous ne pouvons pas les utiliser. Nous avons besoin qu'ils soient présents au moment de l'exécution, soit à travers un dictionnaire de typeclass, soit à travers un argument singleton explicite. (A propos de 'KnownNat', je ne sais pas comment cela fonctionne en termes précis) – chi

+0

Eh bien c'est exactement le point, je m'attends à ce que ces nombres soient calculés au moment de la compilation et ensuite les utiliser pour calculer les types corrects. Toutes les informations pertinentes doivent être disponibles au moment de la compilation. Est-il déraisonnable de penser que si je connais 'a :: Nat' à la compilation, je peux aussi savoir '1 + a'? – fakedrake