2012-06-10 10 views
10

Tengo varias preguntas relacionadas con la función curried. Aquí les pregunto uno por unocurry function preguntas relacionadas en Scala

1) http://twitter.github.com/scala_school/basics.html da un ejemplo de función curried - Pensé que era una definición de función, pero en realidad no lo es. El REPL no reconoce esto como una declaración válida en absoluto.

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

2) ¿Por qué no podemos definir una función a partir del método parcialmente parametrizado? es decir, ¿qué pasa con la siguiente definición?

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) ¿Por qué no podemos hacer una función parcialmente parametrizada al curry? es decir, ¿qué pasa con la siguiente definición?

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) No es válido, porque debe declararse primero. Por ejemplo, así: 'def multiplyThenFilter (a: Int => Int) (b: Int => Boolean) = {List (1,2,3,4) .map (a).filter (b)} ' –

+0

1) El multiplicadorThenFilter ya no está. No fuiste la única persona confundida por eso :-) –

Respuesta

11

Pregunta 1

El ejemplo escuela Scala es confuso-que definitivamente no es una definición. Hay an issue abierto en GitHub, así que tal vez sea un error. Se puede imaginar una definición razonable podría tener este aspecto:

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).)

A continuación, el ejemplo podría ser una función que duplica su entrada y devuelve el resultado en un Some si es menos de 5 y None de lo contrario. Pero nadie sabe exactamente lo que el autor pretendió hasta que haya una respuesta a ese problema.


Pregunta 2

La razón de que su timesTwo no funciona es que el compilador Scala no soporta ese tipo de inferencia de tipos-ver this question y my answer there para un poco de detalle relacionado. Tendrá que ir con uno de los siguientes:

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) _ 

es decir, si quieres la inferencia de tipos aquí se tendrá que utilizar múltiples listas de parámetros. De lo contrario, tienes que ayudar al compilador con el tipo.


Pregunta 3

Para su tercera pregunta, supongamos que tenemos lo siguiente para evitar el tema en su segunda pregunta:

val timesTwo = multiply(2, _: Int) 

Esta es una Function1, que acaba de doesn' t tiene un método curried; necesita un Function2 (o Function3, etc.) para eso.

Simplemente no tiene sentido hablar sobre currying una función con un solo argumento. Currying toma una función con múltiples argumentos y le da una función tomando un solo argumento que devuelve otra función (que a su vez posiblemente tome un solo argumento y devuelva otra función, etc.).

+0

son las dos funciones 'timesTwo' definidas en "val timesTwo = multiply (2, _: Int)" y "val timesTwo = multiply (2) _" en tu respuesta a la pregunta 2 con el mismo tipo? – chen

+0

Sí, ambos son 'Int => Int' (o equivalentemente' Function1 [Int, Int] '). –

Cuestiones relacionadas