2013-03-24 29 views
17

Scrittura di programmi Haskell Mi sono trovato a dover un operatore come questo.:: a -> (a -> b) -> operatore b (Haskell)

(|>) :: a -> (a -> b) -> b 
(|>) = flip ($) 
infixl 0 |> 

Penso che sia utile quando si incollano più funzioni insieme.

tText cs = someFun cs |> 
      lines  |> 
      map (drop 4) |> 
      reverse 

preferisco sopra . perché con |> l'ordine in cui vengono applicate le funzioni è lo stesso che l'ordine in cui sono scritte le funzioni.

tText' cs = reverse  . 
      map (drop 4) . 
      lines  . 
      someFun $ cs 

La domanda è: è questo (|>) qualcosa che già esiste nella/qualche altra libreria di base Prelude? Reimplementare cose semplici è qualcosa di sciocco che vorrei evitare.

Una ricerca di Hoogle non ha aiutato. La cosa più vicina che ho trovato è stata >>> (frecce), ma sembra eccessivo.

+3

No, non lo è, anche se come dici tu ">>>" fa. [C'era un'altra domanda SO sul perché F # usa '|>' dove Haskell usa '.' e' $ ', che è piuttosto rilevante.] (Http://stackoverflow.com/questions/1457140/haskell-composition-vs- fs-pipe-forward-operator) (Nota anche, solo per divertimento, che con '.' o' >>> ', puoi scrivere la tua funzione point-free:' tText = reverse. map (drop 4). lines. someFun', o 'tText = someFun >>> lines >>> map (drop 4) >>> reverse'.) –

+1

Qualche tempo fa, c'era una conversazione sulla mailing list sull'aggiunta di questo alle librerie standard. http://www.haskell.org/pipermail/libraries/2012-November/018832.html –

+4

"l'ordine in cui le funzioni sono applicate è lo stesso dell'ordine in cui sono scritte le funzioni." Bene - questo è il tipo di pensiero che gli Haskellers evitano: non specifichi "fai questo, poi con il risultato fallo, poi ..." ma concentrati sul risultato desiderato, quindi è perfettamente naturale iniziare con l'ultimo passaggio di calcolo. Inoltre, con la valutazione pigra, questo "ultimo" passo sarà in realtà il primo a essere valutato! - Per il tipo procedurale di funzioni, quelle in cui è effettivamente necessario pensare in passaggi sequenziali, Haskell ha Monade, la cui notazione 'do' è sempre" avanti ". – leftaroundabout

risposta

16

No, non c'è nulla in una libreria standard che io conosca. Anni e anni fa un sacco del mio codice importati mia breif, ma a portata di mano modulo Forwards:

> module Forwards where 

> infixl 0 |> 
> infixl 9 .> 

> (|>) = flip ($) 
> (.>) = flip (.) 

ho anche utilizzato lo stesso nome di voi!

In questi giorni non lo uso molto: mi sono abituato all'ordine in cui la composizione della funzione viene utilizzata.

Sentiti libero di usare le tue scorciatoie.

Io uso anche $ meno di quello che ero abituato. Dove ho usato per scrivere

thing = this $ that arg $ an other $ it 

Ora scrivo

thing = this . that arg . an other $ it 
12
+1

E .. 'diagrams' lo definisce come' # '. –

+0

+1 per indicare l'obiettivo. L'apprendimento delle lenti è un buon consiglio. – AndrewC

7

È inoltre possibile definire (|>) come "ID flip" e capire perché questo funziona è una grande lezione di inferenza di tipo mediante unificazione utilizzata in Haskell.

0

Per quanto riguarda la mia esperienza, non conosco nessuna libreria di questo tipo. E se esiste una tale libreria, sconsiglio di usarla.


A meno che non si sta utilizzando il pacchetto lente, io suggerirei di non usare gli operatori definiti esternamente di questo tipo. (In caso di quel pacchetto lenti, si ha realmente bisogno e hanno già un tale operatore.)

Nella mia esperienza, IMHO e tale ...

Nei casi in cui la leggibilità esalta con una composizione in avanti in contrasto con la solita composizione (non solo quando si tratta di lenti), è utile definire un operatore speciale in quel modulo o localmente tramite let o where. Per questo, tendo ad usare singoli simboli Unicode piuttosto che combo ascii.

(·) = flip (.) 
infixl 1 (·) 

(§) = ($) -- left associative, no flip 
infixl 0 (§) 

Alcuni anni fa (quando non c'erano le lenti), ho pensato di definire il mio modulo per questi, anche. Ma poi ho imparato ad usare quel modulo talmente poco frequente che tendevo a reinventare la ruota comunque. Per avere questi operatori in una libreria può anche aumentare lo sforzo di leggere il codice: il lettore deve guardare quegli operatori usati raramente. In tal caso, gli operatori definiti localmente sono decisamente migliori.

Problemi correlati