2011-09-20 17 views
6

F # Le espressioni di calcolo consentono di nascondere la complessità della sintassi monadica dietro uno spesso strato di zucchero sintattico. C'è qualcosa di simile disponibile in Scala?Equivalente alla notazione Haskell o alle espressioni di calcolo F # in Scala?

penso che sia espressioni for ...

Esempio:

val f = for { 
    a <- Future(10/2) // 10/2 = 5 
    b <- Future(a + 1) // 5 + 1 = 6 
    c <- Future(a - 1) // 5 - 1 = 4 
} yield b * c   // 6 * 4 = 24 

val result = f.get 

Ma non si sente veramente giusto. C'è una sintassi migliore?

per exemple in Haskell si avrebbe

 
    main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode 
      toHandle <- getAndOpenFile "Copy to: " WriteMode 
      contents <- hGetContents fromHandle 
      hPutStr toHandle contents 
      hClose toHandle 
      putStr "Done." 

questa differenza di Scala non apparire come un foreach loop. La sintassi di Scala sembra avere un accoppiamento troppo forte con la comprensione di List che è un concetto distinto. Che mi impedisce di scrivere DSL interno (monad) che non sembra strano.

+4

'for' comprehensions ha esattamente ragione. Hanno desugar per 'map' e' flatMap' dietro le quinte, che è esattamente come funziona la notazione Haskell 'do' (eccetto quei metodi sono chiamati' fmap' e '>> =' in Haskell). –

+0

@pelotom Mi piacerebbe vedere una risposta che spieghi un po 'di più. –

+5

@Dan Burton - Questa domanda è stata fatta e ha risposto diverse volte ... Ti rimanderò a questa eccellente risposta: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield/1059501 # 1059501 –

risposta

-2

Sembra che non ci sia una sintassi di questo tipo disponibile in scala e avremmo bisogno di implementarlo da soli usando l'architettura del plugin del compilatore.

+0

Ho pensato di usare le macro-l'hai considerato? –

4

Il pezzo mancante è probabilmente l'uso di = è Scala di per-comprensioni:

val f = for { 
    a <- Future(10/2) // 10/2 = 5 
    b <- Future(a + 1) // 5 + 1 = 6 
    c <- Future(a - 1) // 5 - 1 = 4 
    d = b * c   // 6 * 4 = 24 
} yield d 


val result = f.get 

Con miscelazione giudizioso sia <- e =, si dovrebbe avere tutta la flessibilità di cui avete bisogno.

+1

A volte vorrei che la sintassi 'do' di Haskell deducesse' let' dall'uso di '=' –