2015-09-25 27 views
16

Qual è la differenza tra return e pure da Control.Applicative? Sembra che io possa usare pure anche alla fine di un blocco do?Differenza tra "ritorno" e "puro"

Quindi c'è una situazione in cui si dovrebbe preferire l'una sull'altra (oltre al fatto che tutti si aspettano un return alla fine di un blocco do)?

+6

Non c'è differenza, esistono entrambi per ragioni storiche ("Monade" non è sempre stata una superclasse di "Applicativo"). C'è una proposta per alias 'return' to' pure'. – Lee

+3

Per chiarire, sono uguali se sai che hai a che fare con un 'Monade'. 'pure' è più generale di' return' in quanto restituisce un 'Applicative' quindi non è possibile sostituire tutte le istanze di' return' con 'pure', ma è possibile sostituire' pure' con 'return'. – Lee

+8

@Lee, penso che sia il contrario nella seconda frase. –

risposta

26

In GHC 7.8 e precedenti, Applicative non era una superclasse di Monad. È persino possibile che un'istanza Monad non abbia un'istanza Applicative. C'era, tuttavia, l'aspettativa che pure e return dovessero avere lo stesso comportamento per i tipi che sono istanze di entrambi.

In GHC 7.10, a causa della Functor-Applicative-Monad Proposal, Applicative è ora una superclasse di Monad (class Applicative m => Monad m) ed è ora una regola che pure e return deve essere uguale per tutte le istanze Monad. In effetti, l'implementazione predefinita di return è ora pure, come visto in the source on hackage.

pure potrebbero essere preferiti per return perché non comporta un vincolo Monad, solo Applicative vincolo, rendendo così la funzione più generale. return potrebbe essere preferito a pure in notazione a causa del precedente storico, ma lo pure potrebbe essere utilizzato esattamente per lo stesso effetto.

12

La classe di tipi Applicativo è stata aggiunta dopo Monad e storicamente la classe Monad non è stata una sottoclasse di Applicative. Questo è stato modificato abbastanza recentemente nel Applicative-Monad-Proposal e ciò significa che return a dovrebbe essere equivalente a pure a per ogni istanza Monad.

C'è uno proposal per spostare return fuori dalla classe Monad e trasformarlo in un alias per pure.

Pertanto, quando si ha a che fare con un Monad, si dovrebbe sempre essere in grado di usare pure anziché return. Tuttavia, non è possibile andare dall'altra parte poiché pure ha un tipo più generale di return poiché restituisce solo uno Applicative. Ad esempio la seguente

wontCheck :: Applicative f => f Int 
wontCheck = return 4 

non digitare verifica poiché richiede returnf essere un Monad.

+0

Anche se l'altra risposta è accettata e prima, mi è piaciuto molto il tuo esempio –