Avendo un'idea di what the Comonad typeclass is in Haskell, ho sentito parlare della comonad Store. Ma guardando Control.Comonad.Store.Lazy, non capisco davvero. Cosa significa? Cosa serve? Ho sentito che Store = CoState, il doppio della Monade di Stato. Cosa significa?Qual è la comonad Store?
risposta
È molto più semplice se si guarda la definizione di StoreT itself.
Si può pensare a un "luogo" in una struttura più grande. Ad esempio, uno lens è solo a -> Store b a
; si ottiene il valore del campo b e una funzione b -> a
per reinserire un nuovo valore nel contesto più ampio.
Considerando nella sua forma semplificata, non trasformatore:
data Store s a = Store (s -> a) s
instance Functor (Store s) where
fmap f (Store g s) = Store (f . g) s
instance Extend (Store s) where
duplicate (Store f s) = Store (Store f) s
instance Comonad (Store s) where
extract (Store f s) = f s
cioè duplicate
cambia il s -> a
in un s -> Store s a
che restituisce solo il luogo "aggiornata" dopo la sostituzione del valore, e extract
ripristina l'originale un inserendo il valore nella struttura più grande.
Per quanto riguarda il suo rapporto con Stato va, si poteva guardare in questo modo:
type State s a = s -> (a, s)
type Store s a = (s -> a, s)
Data la seguente definizione di negozio,
data Store s a = Store { peek :: s -> a, pos :: s }
Mi piace pensare di un Store
come un grande magazzino pieno di valori di tipo a
. Ogni valore di tipo a
viene inserito in una posizione contrassegnata da un valore di indice di tipo s
. Finalmente c'è un carrello elevatore parcheggiato in posizione pos
. Il carrello elevatore può essere utilizzato a extract
un valore di tipo a
dal negozio estraendo il valore da dove è parcheggiato. È possibile utilizzare seek
per spostare il carrello elevatore su una nuova posizione assoluta o utilizzare seeks
per spostare il carrello elevatore in una nuova posizione relativa. Per aggiornare tutti i valori del negozio utilizzare fmap
. Infine extend f
è simile a fmap
eccetto che in sostituzione diabbiamo f :: Store s a -> a'
che consente alla funzione di aggiornamento non solo di accedere al valore in fase di aggiornamento, ma anche di accedere alla posizione del valore e accedere ai valori di tutto il resto del negozio. In altre parole, extend
utilizza il valore e il contesto circostante per eseguire l'aggiornamento.
Un'analogia più computerizzata sarebbe quella di pensare a un Store
come un grande piatto di un disco rigido con valori memorizzati in varie posizioni, oltre a una testa parcheggiata in una particolare posizione.
Giusto per espandere la connessione tra Stato e Negozio, tutte le monadi derivano da una composizione di funzioni aggiuntive. È comunemente noto che i functors '(r -> _)' (aka Reader) e '(_, r)' (anche capovolto, ma non si adatta alla solita presentazione di State in Haskell, e non può essere un Istanza di Functor in Haskell) sono aggiunti, e se li componi in un modo ('s -> (_, s)') otterrai una monade, e se li componi nell'altro modo ('(s -> _, s) ') otterrai una comonad. – copumpkin
@copumpkin: È '(_, r)' che non può essere un Functor, non è vero? '(r, _)' è solo 'instance Functor ((,) r)'. – ehird
Sì, scusate, ho erroneamente commentato questa parentesi :) – copumpkin