2014-04-04 11 views
11

Leggendo vari tutorial sulle varie classi tematiche di Haskell, troviamo cose come Monoid, Functor, Monad e così via - che hanno dozzine di istanze. Ma per qualche ragione, quando raggiungiamo lo Arrow, ci sono solo due istanze: funzioni e monadi. In entrambi i casi, l'utilizzo dell'istanza Arrow è meno potente e più difficile rispetto all'utilizzo diretto della cosa sottostante.E le frecce?

Qualcuno ha interessante esempi di frecce? Sono sicuro che ci deve essere un po ', ma non ho mai trovato nessuno scritto su di loro ...

+0

[Relevant] (http: //programmers.stackexchange.it/questions/114681/what-is-the-purpose-of-arrows) – bheklilr

+0

Può qualificare FRP basato su frecce? –

+1

La mia comprensione di Frecce in Haskell è che più o meno ti danno il linguaggio dei circuiti, in cui un componente dipende dalle uscite del precedente. Potresti chiedere come questo sia diverso dalla normale composizione e combinazione di funzioni, ma le normali funzioni non possono portare con sé contesti e strutture extra, mentre le frecce sono più astratte e possono. Questo è il motivo per cui sono molto popolari in FRP, è possibile scrivere codice efficace che sembra puro e può essere ragionato molto facilmente. Vengono anche utilizzati nella libreria Hxt per lo streaming di dati XML tramite calcoli apparentemente puri. – bheklilr

risposta

7

HXT, una libreria che viene utilizzata per l'analisi di XML, è un ottimo esempio per l'utilizzo di frecce (avere guarda quante volte la parola Arrow si presenta nei nomi dei moduli di questo pacchetto!). Dovresti dare un'occhiata al grande tutorial: http://adit.io/posts/2012-04-14-working_with_HTML_in_haskell.html

Ma è anche bene avere il concetto di freccia per le funzioni. Ad esempio il codice

((+1) &&& (*2)) 3 -- result is (4,6) 

seguente solo funziona, perché (->) è un'istanza della classe freccia (L'operatore &&& è definita Control.Arrow).

Grazie allo arrow syntax si ha anche un ottimo strumento per scrivere calcoli complessi in Haskell (funziona anche per funzioni, monadi e filtri XML in HXT).

+0

HXT sembra abbastanza interessante. Qualche commento sul perché la maggior parte delle librerie di parser sono dei funtori applicativi (o monadi), ma questa è una freccia? – MathematicalOrchid

8

Mi piace pensare a Arrow s come grafici aciclici diretti componibili. Ad esempio, una freccia di tipo:

SomeArrow (a, b, c) (d, e, f) 

... si può pensare come un grafico che ha tre archi entranti di tipo a, b e c e tre archi uscenti di tipo d, e e f .

Utilizzando questa interpretazione, le operazioni di composizione di categoria per Arrow s sono come concatenazione orizzontale per i grafici, che collega i bordi insieme:

(.) :: SomeArrow b c -> SomeArrow a b -> Some Arrow a c 

... dove a, b e c possono essere essi stessi tuple. Analogamente, id è solo il grafico identità che inoltra tutte archi entranti per archi uscenti:

id :: SomeArrow a a 

L'altra operazione chiave è (***) che è come concatenazione verticale dei grafici:

(***) :: Arrow a b -> Arrow c d -> Arrow (a, c) (b, d) 

si può pensare che come mettere due grafici fianco a fianco, combinando i loro bordi di input e i bordi di output.

Quindi Arrow si verificano comunemente quando si lavora con grafici aciclici diretti digitati. Tuttavia, il motivo per cui di solito non li vedi spesso perché la maggior parte delle persone associa mentalmente i grafici a strutture di dati non tipizzate e ad alte prestazioni.

+0

Presumibilmente 'ArrowLoop' è il punto in cui il grafico smette di essere aciclico? – MathematicalOrchid

+1

Questo accidentalmente arriva al cuore del perché le frecce non sono terribilmente utili/popolari. Abbiamo già 'Category' per le cose che compongono, e dichiarazioni nella lingua Haskell stessa per cose che esistono nello stesso momento (l'una accanto all'altra), quindi tutto il' Arrow' è la colla per mettere le cose l'una accanto all'altra, e portarli indietro a parte. Il problema è che la colla invertibile è solo delle tuple, che sono spiacevoli. È davvero colpa della tupla. Immagina di sostituire "<*>" in "Applicativo" con "f a -> f b -> f (a, b)". – Cirdec

+0

@MathematicalOrchid Right –

Problemi correlati