2015-10-19 20 views
11

Ultimamente ho avuto il lusso di imparare un po 'di Idris e una cosa che ho trovato estremamente comoda è la! -notation, che mi permette di accorciare il codice monadico all'interno di un non bloccare qualiVersione Haskell di Idris! -notazione (notazione bang)

a' <- a 
b' <- b 
c' <- c 
someFunction a' b' c' 

al molto più bello

someFunction !a !b !c 

Ora, quando scrivo il codice in Haskell, sto cercando qualcosa di simile, ma per quanto ne so non esiste (e il carattere bang è ovviamente già utilizzato per la corrispondenza di pattern rigorosi). C'è un modo per evitare di avere un po 'di banali frecce a sinistra all'interno di un blocco? Forse un'estensione che aggiunge una regola di riscrittura o qualcosa del genere?

risposta

20

Dal momento che ogni monade è un Applicative (con GHC> = 7.10) possiamo scrivere

someFunction <$> a <*> b <*> c 

Nota che se someFunction restituisce un valore monadico di tipo m T, il precedente restituirà m (m T), che rischia non quello vogliamo (come @pigworker sottolinea sotto). Possiamo però join i due strati insieme:

join $ someFunction <$> a <*> b <*> c 
+1

Risposta perfetta, esattamente ciò di cui avevo bisogno. Credo di dover passare un po 'più di tempo con Applicative. Grazie. – Karl

+2

Qual è il tipo di 'someFunction'? Il suo tipo di ritorno è monodico? – pigworker

+0

@pigworker Buon punto, ho davvero trascurato quel caso. – chi

2

Parlando di frecce ...

import Control.Arrow 

a' = Kleisli $ const a 
b' = Kleisli $ const b 
c' = Kleisli $ const c 

foo = (`runKleisli`()) $ 
    (a' &&& b') &&& c' >>> uncurry (uncurry someFunction) 

Non che io consiglio questo.

+4

Ew, ew, ew. CHE COSA? – dfeuer