2015-10-19 7 views
11

Ich hatte den Luxus, ein bisschen von Idris in letzter Zeit zu lernen und eine Sache, die ich extrem praktisch gefunden habe, ist die! -Notation, die mich in einem monadischen Code verkürzen lässt blockiere wieHaskell Version von Idris! -Notation (Bang Notation)

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

auf die viel schöner

someFunction !a !b !c 

Nun, wenn ich Code in Haskell schreiben, ich bin auf der Suche nach etwas ähnliches, aber soweit ich sagen kann, es existiert nicht (und der Bang-Charakter wird offensichtlich bereits für den strikten Mustervergleich verwendet). Gibt es eine Möglichkeit, einen Haufen trivialer linker Pfeile in einem Do-Block zu vermeiden? Vielleicht eine Erweiterung, die eine Rewriting-Regel hinzufügt, oder etwas Ähnliches?

Antwort

20

Da jede Monade ein Applicative ist (mit GHC> = 7.10) wir

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

Hinweis schreiben können, dass, wenn someFunctionm T einen monadischen Wert vom Typ zurückgibt, wird die oben m (m T) zurückkehren, das, was wahrscheinlich nicht wir wollen (wie @pigworker unten zeigt). Wir können jedoch join die beiden Schichten zusammen:

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

Perfekte Antwort, genau das, was ich brauchte. Ich denke, ich muss etwas mehr Zeit mit Applicative verbringen. Vielen Dank. – Karl

+2

Was ist der Typ von 'someFunction'? Ist der Rückgabetyp monadisch? – pigworker

+0

@pigworker Guter Punkt, ich habe diesen Fall tatsächlich übersehen. – chi

2

von Pfeilen Speaking ...

import Control.Arrow 

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

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

Nicht, dass ich dies empfehlen.

+4

Ew, ew, ew. WAS? – dfeuer