2013-06-10 11 views
10

According to the Haskell wikibook, un Monad chiamato m è un Functor con due operazioni aggiuntive:Non è una monade, ma che cos'è?

unit :: a -> m a 
join :: m (m a) -> m a 

Che bello, ma ho qualcosa di leggermente diverso. Riflettendo sui dettagli cruenti, ho un tipo che ha buone funzioni unit e join, ma il suo fmap non si comporta bene (fmap g . fmap f non è necessariamente fmap (g.f)). Per questo motivo, non può essere creato un'istanza di Monad. Ciò nonostante, mi piacerebbe dargli il maggior numero possibile di funzionalità generiche.

Quindi la mia domanda è: quali strutture teoriche di categoria sono simili alle monadi in quanto hanno un unit e join?

Mi rendo conto che a un certo livello, la domanda di cui sopra è mal definita. Per le monadi le definizioni unit e join hanno senso solo in termini di definizione fmap. Senza fmap, non è possibile definire nessuna delle leggi di monade, quindi qualsiasi definizione di unit/join sarebbe ugualmente "valida". Quindi sto cercando funzioni diverse da fmap che potrebbe avere senso definire alcune leggi "non-monade" su queste funzioni unit e join.

+5

Puoi descrivere più sulla struttura che hai, e ciò che in particolare fa sì che a fallire la legge di fusione per 'fmap'? – luqui

+2

Suppongo che tu abbia "modificato" in modo specifico 'fmap' in modo tale che' join' soddisfi la 2a legge monad? Normalmente, si ottiene quasi sempre 'fmap g. fmap f ≡ fmap $ f.g' solo automaticamente. – leftaroundabout

+0

@luqui Sono più interessato in generale che solo in questo caso specifico, ma è una distribuzione normale. Se si pensa a 'fmap' come ad applicare una funzione ad ogni punto di una distribuzione, quindi' fmap' obbedisce solo alle leggi di 'Functor' per addizione e moltiplicazione. 'unit' si sta allenando su un singolo punto di dati, e' join' sta unendo una "distribuzione normale delle normali distribuzioni" in una singola distribuzione normale. Ovviamente, ciò richiede alcuni vincoli sui parametri, quindi non può essere fatto affatto usando le classi di tipo 'Base' e ​​sto usando' ConstraintKinds' per giocarci. –

risposta

3

Bene ecco una legge che si dovrebbe avere con solo unit e join. Dato x :: m a,

join (unit x) = x 

Per dimostrare che questo non appena arrivato dal nulla, cominciamo con una legge monade esistente:

return x >>= f = f x 

Dato che m >>= f = join (fmap f m)

join (fmap f (return x)) = f x 

Seleziona f = id

join (fmap id (return x)) = id x 

usare la legge funtore che fmap id = id

join (id (return x)) = id x 

Utilizzare l'ovvio id a = a

join (return x) = x 
Problemi correlati