Sto scrivendo una classe di tipo per la mia libreria pipes
per definire un'interfaccia astratta per tipi-Proxy
-like. La classe di tipo simile a:Vincolo di una variabile derivata di una classe di tipo o di un'istanza
class ProxyC p where
idT :: (Monad m) => b' -> p a' a b' b m r
(<-<) :: (Monad m)
=> (c' -> p b' b c' c m r)
-> (b' -> p a' a b' b m r)
-> (c' -> p a' a c' c m r)
... -- other methods
Sto anche scrivendo le estensioni per il tipo Proxy
che sono di forma:
instance (ProxyC p) => ProxyC (SomeExtension p) where ....
... e vorrei questi casi per essere in grado imporre un ulteriore vincolo che se m
è p a' a b' b m
per tutti a'
, a
, b'
e b
.
Tuttavia, non ho idea di come codificarlo in modo pulito come un vincolo per la classe ProxyC
o per le istanze. L'unica soluzione che attualmente conosco è quello di fare qualcosa di simile la codifica nelle firme dei metodi della classe:
(<-<) :: (Monad m, Monad (p b' b c' c m), Monad (p a' a b' b m))
=> (c' -> p b' b c' c m r)
-> (b' -> p a' a b' b m r)
-> (c' -> p a' a c' c m r)
... ma speravo ci sarebbe una soluzione più semplice e più elegante.
Edit: E neppure che l'ultima soluzione funziona, dal momento che il compilatore non dedurre che (Monad (SomeExtension p a' a b' b m))
implica (Monad (p a' a b' b m))
per una precisa scelta di variabili, anche se dato il seguente esempio:
instance (Monad (p a b m)) => Monad (SomeExtension p a b m) where ...
Modifica # 2: la soluzione successiva sto considerando è solo duplicare i metodi per la classe Monad
all'interno della classe ProxyC
:
class ProxyC p where
return' :: (Monad m) => r -> p a' a b' b m r
(!>=) :: (Monad m) => ...
... e quindi istanzialo con ciascuna istanza ProxyC
. Ciò sembra a posto per i miei scopi poiché i metodi Monad
devono essere utilizzati solo internamente per la scrittura di estensioni e il tipo originale ha ancora un'istanza corretta Monad
per l'utente downstream. Tutto ciò non fa altro che esporre i metodi Monad
al writer di istanze.
AFAIK lo puoi fare solo con brutti hack, come f.e. Edward Kmett fa in http://hackage.haskell.org/packages/archive/constraints/0.3.2/doc/html/Data-Constraint-Forall.html –