Podczas gry wokół pakietu objective zauważyłem, że następujący typ ma interesującą właściwość.Jak nazywa się ten funktor używający RankNTypes?
> {-# LANGUAGE RankNTypes #-}
> data N f r = N { unN :: forall x. f x -> (x, r) }
To jest Funktor.
> 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)
Po kilku godzinach google/hoogle, dałem się znaleźć żadnych istniejący moduł, który zawiera tego typu. Co to jest ten typ? Jeśli jest dobrze znana, jak się nazywa? Czy jest to użyteczne, czy ignorowane, ponieważ bezużyteczne?
To nie jest moje 100% oryginalne dzieło, ponieważ N został wyprowadzony z Obiektu znalezionego w pakiecie celu.
> data Object f g = Object {
> runObject :: forall x. f x -> g (x, Object f g)
> }
N f
jest funktora co daje Object f Identity
gdy Fix wniosek.
Poniżej znajduje się fakt o tym typie i dlaczego uważam, że jest interesujący.
N przekształca program Reader to Writer, i na odwrót. (Tutaj użyłem (=) symbol izomorfizmu między typami)
N ((->) e) r
= forall x. (e -> x) -> (x, r)
= (e, r)
N ((,) d) r
= forall x. (d, x) -> (x, r)
= d -> r
N konwertuje Store comonad do monady państwa, ale odwrotna nie jest prawdziwa.
> 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 nie może brać Być może.
N Maybe r
= forall x. Maybe x -> (x, r)
= forall x. (() -> (x, r), x -> (x, r))
= Void -- because (() -> (x, r)) can't be implemented
Następujące funkcje mogą być zabawne. Nie mogłem tego zrobić odwrotnie.
> 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'
Cały wpis jest piśmienny Haskell (.lhs).
Nie znam imienia, ale piszę to jako '(forall x. Fx -> ((,) r) x)' i staje się czymś, co można przekazać do 'Control.Comonad.Cofree. hoistFree'. – Gurkenglas
@chi Nie ma 'g' w' N'. To ustawienie 'g ~ Identity' w' Object f g'. Jeśli upuścisz nieinteresujące 'Tożsamość' od' forall x. f x -> Tożsamość (x, Object f Tożsamość) 'dostajesz' dla all x. f x -> (x, Object f) '. Jeśli zastąpisz rekursywne wystąpienie 'Object f' nowym parametrem' r', otrzymasz 'forall x. f x -> (x, r) ', czyli' N f r'. 'Fix (N f)' umieszcza rekursywne wystąpienie z powrotem tam, gdzie było 'r'. – Cirdec
To wygląda jak ['Ran'] (https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor-Ran.html#t:Ran), ale mieszanie i dopasowywanie profunktorów i bifunktorów. 'forall x. f x -> x' jest indeksem do 'f'. Druga część to czytnik ze środowiska 'forall x. f x', odczytywanie struktury 'f', ale nie jej wartości. – Cirdec