2012-06-10 18 views
10

Ho diverse domande relative alla funzione al curry. Qui li chiedo uno per unodomande relative a funzioni elaborate in Scala

1) http://twitter.github.com/scala_school/basics.html fornisce un esempio di funzione al curry - ho pensato che fosse una definizione di funzione, ma in realtà non lo è. Il REPL non lo riconosce come una dichiarazione valida.

multiplyThenFilter { m: Int => m * 2 } { n: Int => n < 5} 

2) Perché non è possibile definire una funzione da un metodo parzialmente parametrizzato? cioè, cosa c'è di sbagliato nella seguente definizione?

scala> def multiply(m: Int, n: Int): Int = m * n 
multiply: (m: Int, n: Int)Int 

scala> val timesTwo = multiply(2,_) 
<console>:11: error: missing parameter type for expanded function ((x$1) => multiply(2, x$1)) 
     val timesTwo = multiply(2,_) 
           ^

3) Perché non è possibile eseguire una funzione parzialmente parametrizzata in fase di elaborazione? cioè, cosa c'è di sbagliato nella seguente definizione?

scala> (multiply(_,_)).curried 
    res13: Int => (Int => Int) = <function1> // THIS IS OK 

scala> (multiply(20,_)).curried 
<console>:12: error: missing parameter type for expanded function ((x$1) => multiply(20, x$1)) 
       (multiply(20,_)).curried 
         ^
+0

1) Non è valido, perché deve essere dichiarato per primo. Ad esempio, in questo modo: 'def multiplyThenFilter (a: Int => Int) (b: Int => Boolean) = {List (1,2,3,4) .map (a).filter (b)} ' –

+0

1) Il multiplyThenFilter è scomparso ora. Non sei l'unica persona confusa da questo :-) –

risposta

11

Domanda 1

L'esempio Scala scuola è confusa-non è sicuramente una definizione. C'è an issue aperto per questo su GitHub, quindi forse è un bug. Si può immaginare una definizione ragionevole potrebbe essere simile a questo:

def multiplyThenFilter(f: Int => Int)(p: Int => Boolean): Int => Option[Int] = { 
    i => 
    val j = f(i) 
    if (p(j)) Some(j) else None 
} 

(o, equivalentemente, f andThen (Some(_) filter p).)

Poi l'esempio potrebbe essere una funzione che raddoppia il suo input e restituisce il risultato in una Some se si tratta di meno di 5 e un None in caso contrario. Ma nessuno sa esattamente cosa l'autore abbia inteso fino a quando non ci sarà una risposta a questo problema.


Domanda 2

La ragione per cui il vostro timesTwo non funziona è solo che il compilatore Scala non supporta questo tipo di inferenza di tipo-see this question e my answer there per un po 'di dettagli relativi. Avrai bisogno di andare con uno dei seguenti:

def multiply(m: Int, n: Int): Int = m * n  
val timesTwo = multiply(2, _: Int) 

def multiply(m: Int)(n: Int): Int = m * n  
val timesTwo = multiply(2) _ 

cioè se si desidera che l'inferenza dei tipi qui avrete bisogno di utilizzare più liste di parametri. Altrimenti devi aiutare il compilatore ad uscire con il tipo.


Domanda 3

Per la terza domanda, assumere abbiamo la segue per evitare il problema della tua seconda domanda:

val timesTwo = multiply(2, _: Int) 

Questo è un Function1, che ha appena doesn' t avere un metodo curried - è necessario un Function2 (o Function3, ecc.).

Non ha senso parlare di eseguire una funzione con un singolo argomento. Il curry prende una funzione con più argomenti e ti dà una funzione prendendo un singolo argomento che restituisce un'altra funzione (che a sua volta prende un singolo argomento e restituisce un'altra funzione, ecc.).

+0

sono le due funzioni 'timesTwo' definite in "val timesTwo = moltiplicare (2, _: Int)" e "val timesTwo = moltiplicare (2) _" nella tua risposta alla domanda 2 con lo stesso tipo? – chen

+0

Sì, sono entrambi 'Int => Int' (o equivalentemente' Function1 [Int, Int] '). –

Problemi correlati