2016-04-29 17 views
11

Durante il gioco del pacchetto objective, ho notato che il seguente tipo ha proprietà interessanti.Qual è il nome di questo functor che utilizza RankNTypes?

> {-# LANGUAGE RankNTypes #-} 
> data N f r = N { unN :: forall x. f x -> (x, r) } 

È un Functor.

> instance Functor (N f) where 
> fmap f (N nat) = N $ fmap (fmap f) nat 
>   -- or, = N $ \fx -> let { (x,a) = nat fx } in (x, f a) 

Dopo poche ore di google/Hoogle, ho rinunciato a trovare alcuna modulo esistente che include questo tipo. Che cos'è questo tipo? Se è noto, come si chiama? È utile o ignorato perché inutile?

Questa non è la mia creazione originale al 100%, poiché N derivava da Oggetto trovato nel pacchetto obiettivo.

> data Object f g = Object { 
>  runObject :: forall x. f x -> g (x, Object f g) 
> } 

N f è un Functor che produce Object f Identity quando Fix viene applicato.


Di seguito è riportato un fatto su questo tipo e perché ho pensato che fosse interessante.

N converte il Reader in Writer, viceversa. (Qui ho usato() = simbolo per isomorfismo tra i tipi)

N ((->) e) r 
= forall x. (e -> x) -> (x, r) 
= (e, r) 

N ((,) d) r 
= forall x. (d, x) -> (x, r) 
= d -> r 

N converte Conservare comonad alla monade Stato, ma inversa non è vero.

> data Store s a = Store s (s -> a) 
> type State s a = s -> (s, a) 

N (Store s) r 
= forall x. (s, (s -> x)) -> (x, r) 
= forall x. s -> (s -> x) -> (x, r) 
= s -> (s, r) 
= State s r 

N (State s) r 
= forall x. (s -> (s, x)) -> (x, r) 
= forall x. (s -> s, s -> x) -> (x, r) 
= forall x. (s -> s) -> (s -> x) -> (x, r) 
= (s -> s) -> (s, r) -- ??? 

N non può prendere Forse.

N Maybe r 
= forall x. Maybe x -> (x, r) 
= forall x. (() -> (x, r), x -> (x, r)) 
= Void  -- because (() -> (x, r)) can't be implemented 

La seguente funzione potrebbe essere divertente. Non potrei farlo è inverso.

> data Cofree f a = Cofree a (f (Cofree f a)) 
> data Free f a = Pure a | Wrap (f (Free f a)) 

> unfree :: Free (N f) r -> N (Cofree f) r 
> unfree (Pure r) = N $ \(Cofree a _) -> (a, r) 
> unfree (Wrap n_f) = N $ 
> \(Cofree _ f) -> let (cofree', free') = unN n_f f 
>     in unN (unfree free') cofree' 

intero post è alfabetizzata Haskell (.lhs).

+2

so nessun nome per questo, ma lo scrivo come '(forall x fx -.> ((,) R) x)' e diventa qualcosa che può essere passato a 'Control.Comonad.Cofree. hoistFree'. – Gurkenglas

+1

@chi Non c'è 'g' in' N'. Sta impostando 'g ~ Identity' in' Object f g'. Se si rilascia il 'Identity's' poco interessante da 'forall x. f x -> Identità (x, Object f Identity) 'si ottiene' per tutto x. f x -> (x, Object f) '. Se si sostituisce l'occorrenza ricorsiva di 'Object f' con un nuovo parametro' r' si ottiene 'forall x. f x -> (x, r) ', che è' N f r'. 'Correggi (N f)' riporta l'occorrenza ricorsiva nel punto in cui 'r' era. – Cirdec

+0

Questo sembra ['Ran'] (https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor-Ran.html#t:Ran), ma mescolando e abbinando i profunctors ei bifunctors. 'per tutto x. f x -> x' è un indice in 'f'. L'altra parte è un lettore dall'ambiente di 'forall x. f x', leggendo la struttura di 'f' ma non i suoi valori. – Cirdec

risposta

2

Lo chiamo un funtore "gestore". Object usato per essere definito utilizzando il functor gestore prima ho rilasciato obiettivo.

Sì, questo functor è interessante - Cofree (Handler f) ha un getter pubblico e Free (Handler f) è un mortal object. Forse avrei dovuto spedire il gestore del gestore ...

1

Anche se è già risposta, ho trovato un'altra risposta alla domanda da solo.

Il tipo N era la rappresentazione a livello di valore della classe di tipo Pairing, descritta nei seguenti articoli.

Free for DSLs, cofree for interpreters

Cofree Comonads and the Expression Problem (Paring si chiama doppio qui)

Accoppiamento e N sono cose stesse

La definizione di abbinamento è questo.

> class Pairing f g where 
> pair :: (a -> b -> c) -> f a -> g b -> c 

f e N f è Pairing.

> instance Pairing f (N f) where 
> pair k fa nb = uncurry k $ unN nb fa 

N può essere rappresentato in termini di Pairing.

> data Counterpart f r = forall g. Pairing f g => Counterpart (g r) 
> 
> iso1 :: N f r -> Counterpart f r 
> iso1 = Counterpart 
> 
> iso2 :: Counterpart f r -> N f r 
> iso2 (Counterpart gr) = N $ \fx -> pair (,) fx gr 

C'è un'istanza Free-vs-cofree, che corrisponde al mio unfree. Altre istanze interessanti sono anche definite negli articoli.

> instance Pairing f g => Pairing (Free f) (Cofree g) where 
> pair = undefined -- see link above 

allungabile Accoppiamento PairingM per oggetto

ex articolo goes to estende Accoppiamento di fare calcoli all'interno di una Monade m.

> class PairingM f g m | f -> g, g -> f where 
> pairM :: (a -> b -> m r) -> f a -> g b -> m r 

Se riscriviamo PairingM ad una forma simile a N, otteniamo nuovamente l'oggetto.

> -- Monad m => HandlerM' f m r ~ HandlerM f m r 
> data HandlerM' f m r = forall g. PairingM f g m => HandlerM' (g r) 
> data HandlerM f m r = HandleM { runHandlerM :: forall x. f x -> m (x, r) } 
> 
> -- Fix (HandlerM f m) ~ Object f m 
> -- Free (HandlerM f m) ~ (mortal Object from f to m) 
Problemi correlati