Siamo tutti innamorati dello do
, ed ero curioso di sapere se forse questa sorta di sintassi alternativa sarebbe teoricamente utile al di fuori del mondo della monade. Se sì, quali altri tipi di calcoli semplificherebbe? Ad esempio, avrebbe senso avere qualcosa di equivalente per Applicativo?Haskell: La notazione "fare" può essere utile in contesti diversi dalle monadi?
risposta
Potrebbe essere utile prendere in considerazione, per quanto riguarda la notazione do
, di cosa si tratta effettivamente buono per. Come sottolinea Travis Brown, in precedenza ho sostenuto l'uso di uno stile di "applicazione di funzione" con Monad
s e tipi correlati, ma c'è anche un altro aspetto positivo: Alcune espressioni semplicemente non possono essere scritte in modo pulito nella funzione diretta stile applicativo. Ad esempio, la seguente possibile effettuare rapidamente stile applicativa goffa:
- intermedi utilizzati in più sottoespressioni, a diverse profondità di annidamento
- argomenti della funzione più esterna utilizzati profondamente annidato in subespressioni
- scomode o incoerenti ordine argomentativo, cioè bisogno di applicare parzialmente una funzione a qualcosa di diverso dal primo argomento
- Controllo di flusso profondamente incorporato basato su risultati intermedi, con sottoespressioni condivise tra rami
- Modello di corrispondenza o n risultati intermedi, in particolare nel caso di estrazione di parte di conseguenza, utilizzando tale per ulteriore calcolo, poi ricostruire una versione modificata come risultato successivo
Scrivi funzione come una singola espressione generalmente richiede sia più lambda nidificati o il tipo di sciocchezze offuscanti e assurde che danno a uno stile senza punti un brutto nome. Un blocco do
, d'altra parte, fornisce uno zucchero sintattico per un semplice scope annidato di risultati intermedi con il flusso di controllo incorporato.
Normalmente si sarebbe probabilmente estrarre tali sottoespressioni e metterli in una clausola where
o qualcosa del genere, ma dal momento che i valori comuni formano una monade con l'applicazione funzione (>>=)
--namely il Identity
Monade - si potrebbe plausibilmente scrivere un tale funzione in un blocco do
, anche se le persone potrebbero guardarti in modo divertente.
Oltre la roba scoping/vincolante, l'altra cosa un blocco do
fa per voi è Elide l'operatore che le catene sottoespressioni insieme. Non è troppo difficile immaginare altri casi in cui sarebbe bello avere una notazione per "combinare queste espressioni usando questa funzione all'interno di questo blocco", e quindi lasciare che il compilatore riempia gli spazi vuoti.
Nel caso facile, in cui le espressioni hanno tutte lo stesso tipo, inserirle in un elenco e quindi piegarle funziona bene: creare stringhe in questo modo utilizzando unwords
e unlines
, ad esempio. Il vantaggio di do
è che combina espressioni con struttura comune e tipi compatibili, ma non identici.
Infatti, lo stesso principio generale vale la notazione "staffa linguaggio" dalla carta Applicative
: Dove do
blocchi utilizzano newlines elidere costruzione monadic, staffe idiom utilizzano giustapposizione elidere applicazione funzione sollevato. Il proc
notazione per Arrow
è simile, e altri concetti potrebbe essere pulito espressa in tal modo, così, ad esempio:
- Composizione strutture di dati, ad esempio fondendo set di risultati di qualche tipo, elidendo la funzione di unione
- Altri linguaggi applicativi funzione, come stile "pipe avanti" argomento della prima, elidendo l'operatore applicazione
- calcoli paralleli, elidendo la funzione di aggregazione risultato
Anche se non è troppo difficile rendere molti di questi in un singolo tipo o in un'istanza completa Monad
, potrebbe essere bello avere un bit di zucchero sintattico unificato ed estensibile per il concetto generale. C'è sicuramente un filo comune che lega tutti questi e altri, ma questo è un argomento molto più ampio non relativo alla sintassi ...
C'è un preprocessore in GHC di fare proprio questo per le frecce: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/arrow-notation.html
Applicative
ha (molto più limitato, e più compatto) Idiom staffe, vedere Applicative Programming with Effects, di pagina 4. Conor McBride Strathclyde Haskell Ambiente ha messo in atto questi , Credo.
Non vedo come generalizzare questo tipo di sintassi speciali, ma forse non ci ho pensato abbastanza.
mia sensazione è che many Haskell programmers don't love do
a tutti, e uno degli argomenti comuni a favore di usare Applicative
quando non è necessario il pieno potere di Monad
è che i combinatori <$>
, <*>
, ecc permettono una chiara e concisa stile di codifica.
Anche per il codice monadico, molte persone preferiscono utilizzare =<<
in modo esplicito invece della notazione do
. camccann 's answer to your previous question about <*>
offre un argomento fantastico per questa preferenza.
Tendo a scrivere le mie prime bozze utilizzando do
e quindi sostituisco con i combinatori durante la revisione. Questa è solo una questione della mia (in) esperienza e gusto: spesso è più facile per me abbozzare le cose in modo più imperativo (che è più conveniente con do
), ma penso che il codice non-do
di solito sia più carino.
Per le frecce, d'altra parte, non riesco a immaginare di non utilizzare proc
e command do
. Le tuple diventano così brutte così rapidamente.
Il do
notazione è fondamentalmente un modo di dire "trasformare a lambda come necessario e distribuire >>=
tra le righe".
Quando è ovvio quale operatore viene utilizzato per rollare tutto, è bello omettere e sfruttare l'operatore "newline".
Newline programmabile sarebbe un buon modo per accedere alla lista di makings, catene applicative, & c. Per creare elenchi, è necessario anche un "outdent programmabile". In realtà, si può solo prendere i tre bit significativi e falli sovraccaricabile:
- Begin di
do
. - tra
do
s. - Fine
do
.
Quindi probabilmente non dovresti chiamarlo più do
. Forse dovrebbe essere solo una parentesi.
Le parentesi di idioma formano un buon modo di pensare a Applicativi, ma non sono l'unica possibile estensione di sintassi.
Philippa Cowderoy pubblicato una proposta di "Applicative do" notazione per Haskell-bar un po 'indietro con l'osservazione che ogni funzione che sembra un po' come:
foo = do
x <- bar
y <- baz
quux y 1234 x
dove le variabili vincolate da <-
si verificano solo nel l'ultima riga potrebbe essere implementata con Applicative - In realtà ho implementato una macro basata sulla regola della sintassi per questo nello schema, che ho chiamato 'ado'.
Ciò è utile nei casi in cui l'ordine degli effetti applicative differenzia dalla "ordine naturale" e presupponendo l'esistenza di 'ado' in Haskell sarebbe solo desugar a:
foo = (\x y -> quux y 1234 x) <*> bar <*> baz
Tuttavia, lo scoping lessicale le regole sono un po 'sconcertanti.
C'è una generalizzazione di monadi che si adatta alla notazione do
- monade parametrizzate. Vedi Beyond Monads di sigfpe. Esempio di utilizzo:
test1' = do put 1
x <- get
put (show x)
y <- get
return (x,y)
Questa è una "monade di stato" che memorizza prima un numero e quindi una stringa.
BlazeHtml sta utilizzando do
-notation quando in realtà è solo una Monoid
(anche se avvolto come Monad
poter utilizzare do
).
Quindi una notazione simile per Monoid
s sarebbe utile lì.
Se si guarda il codice del mio gioco "Defend The King", quindi faccio anche un sacco di mconcat
e, come BlazeHtml, trarrebbe vantaggio da una sintassi dall'aspetto piacevole.
- 1. Dezuccheraggio do-notazione per Monadi
- 2. Notazione sommatoria in Haskell
- 3. Come si combinano le monadi in Haskell?
- 4. Scala equivalente a Haskell monadi
- 5. Sono spazi dei nomi poi così utile in contesti?
- 6. Versione Haskell di Idris! -notazione (notazione bang)
- 7. Haskell è stato progettato per incoraggiare la notazione ungherese?
- 8. Riutilizzo del codice in diversi contesti rspec
- 9. La notazione RPN (notazione polacca inversa) o Postfix può essere derivata dall'espressione regolare
- 10. Haskell: gestione delle eccezioni in non-IO monadi
- 11. Monadi Haskell e un errore che non richiede una stringa
- 12. Come può essere utile sovraccaricare l'operatore "chiamata di funzione"?
- 13. Webstorm può essere utile con le catene di linguaggio Chai?
- 14. Come può {} + [] e [] + {} risultati essere diversi
- 15. Fare un'istanza Leggi in Haskell
- 16. legano Specializzata per monadi oltre typeclasses speciali in Haskell
- 17. Che cosa può fare uno studente di computer del secondo anno che potrebbe essere considerato utile in futuro?
- 18. Questo interprete di notazione (notazione polacca inversa) di notazione Python può essere reso più efficiente e preciso?
- 19. Scopo e relazione dei diversi contesti in primavera
- 20. Can ASP.NET MVC Views può essere riutilizzato in diversi progetti?
- 21. I contesti dei dati dovrebbero essere statici?
- 22. Scala equivalente di do-la notazione di Haskell (ancora una volta)
- 23. Quando si può specificare una lista di esportazione vuota può essere utile?
- 24. casi sovrapposti ruotando Monadi in Semigruppi
- 25. Elegante caso di haskell/gestione degli errori nelle monadi sequenziali
- 26. Autenticazione LDAP con `ldap-haskell`: può essere reso sicuro?
- 27. Contesti per Emacs
- 28. Diversi livelli di stato interagenti in haskell
- 29. Questo esempio di haskell può essere più breve?
- 30. Quando la @ diventa utile?
Uomo, mi sento un po 'male - hai superato due volte i upvotes qui e anche collegato a una delle mie risposte precedenti, ma la mia risposta è stata accettata invece ... per quello che vale, sostengo con tutto il cuore questo risposta! –