2011-09-11 16 views
10

Soy nuevo e ingenuo para scala. Simplemente sepa cómo definir un tipo de función como Establecer aquí (solo como un ejemplo).¿Cómo usar el tipo de función en scala dentro de definido en tipo significativamente?

type Set = Int => Boolean 

def set(i: Int): Set = n => n == i 
def contains(s: Set, i: Int) = s(i) 

También leí la wiki de tipo de función de agnóstico de idioma. Parece que C#, C, Haskel también tienen la gramática similar. http://en.wikipedia.org/wiki/Function_type.

Mi pregunta es en cuyo caso prefiere definir uno de este tipo de función de tipo abstracto y usarlo, ¿Y no hay otra opción para alcanzar el mismo objetivo? Comparando para definir directamente un método concreto usando def

O puedo perder el requisito, decir usando este tipo de función, puedo hacer que el código se vea mucho mejor. Para que pueda saber más sobre el tipo de función.

Aquí mi principal parte interesada es type Set = Int => Boolean, cuando quiere abstraerlo? Estoy buscando un caso de uso de la vida real, y cómo implementarlo en un método concreto en scala grammer. Por ejemplo, este es un poco complejo.

type Set2 = (Int,Int,String) => (Boolean => Int) => (Boolean => Int). 

Sé que se llama tipos de mayor nivel. La gramática en sí misma es significativa. Pero solo necesito ejemplos más simples de la vida real para los principiantes de Scala.

Encontré esta respuesta describiendo para ello. What is a higher kinded type in Scala?

Pero todavía se ve un poco oscuro para mí. Prefiero una respuesta simple para principiantes. Parece que la función en sí misma no requirió nada excepto el parámetro y el tipo de resultado para la implementación mentoda. Por ejemplo, si el resultado (booleano) no proviene del parámetro (Int), aún se compila.

def set(i: Int): Set1 = aa => new Date().getDate() == i 

Am I lostanding it right?

¡Avísame por qué esta pregunta no es clara o mala, así que puedo mejorarla, señor!

+0

Tu gramática es intrincada y la selección de palabras es extraña o sencilla. Por ejemplo '¿hay alguna necesidad especial que prefiera definir? No tiene mucho sentido, y' necesidad 'probablemente debería haber sido' requisito '. Otros ejemplos son 'ingenuo' en la parte superior y' objetivo' (objetivo) en la única pregunta que haces. Ese es el otro problema aquí: una pregunta debería ser una pregunta. Termina en '?', Y se establece como una pregunta. Aquí, la pregunta está en el medio del texto, el medio incluso de un párrafo. No te he rechazado, pero no estás siendo claro. –

+0

@ Daniel, he actualizado la pregunta. Eres libre de corregir la palabra y la gramática incorrectas y todo lo que quieras corregir. –

+0

@ Daniel, En realidad, no tengo claro cómo usar este tipo de función en el estuche correcto. Tal como el tipo Set2 = (Int, Int, String) => (Boolean => Int). Puede ser aún más complicado. –

Respuesta

28

La palabra clave type en Scala crea un alias para un tipo determinado. Por ejemplo:

scala> type Str = String 
defined type alias Str 

scala> val greeting: Str = "Hello World!" 
greeting: Str = Hello World! 

Esto es muy similar a lo que hizo:

scala> type Set = Int => Boolean 
defined type alias Set 

scala> val isEven: Set = _ % 2 == 0 
isEven: Int => Boolean = <function1> 

scala> println(isEven(4)) 
true 

scala> println(isEven(5)) 
false 

Aunque tipo alias pueden a veces ser útil para fines de aclaración, la documentación no es su caso de uso primario. El sistema de tipos de Scala es muy sofisticado. Por ejemplo, hay una alternativa a los genéricos, a saber, los tipos abstractos. Considere esto:

// Generics 
abstract class GenericAbstraction[TypeArgument] 
class GenericConcrete extends GenericAbstraction[String] 

// Abstract types 
abstract class TypeAbstraction { 
    type TypeArgument 
} 
class TypeConcrete extends TypeAbstraction { 
    type TypeArgument = String 
} 

Estos ejemplos de código, básicamente, lograr lo mismo, pero hay situaciones en las que necesita tipos abstractos, pero no puede (o no debe) utilizar los genéricos. Puede encontrar más información here.

+1

Gracias, agilesteel. Puedo sentir tu punto. Limpia todo mi malentendido. ¿Puedo usarlo para verificar tipos? Para probar una función es el subtipo de esta función abstracta +1 - Clark Bao hace 2 minutos editar –

+0

No sabría por qué no puedes. – agilesteel

+0

Sí. Intenté con println (set (1) .isInstanceOf [Set]), y devuelve true. –

1

Se puede definir un literal de la función de la siguiente manera:

val incrementor = (x: Int) => x + 1 

o si tiene algún contexto que puede ser utilizado por la inferencia de tipos de Scala, puede utilizar las formas reducida como:

val listOfInt = List(1, 2, 3, 4, 5) 

listOfInt map {x => x + 1} 
listOfInt map {_ + 1} 

o incluso

listOfInt map {1 +} 

Estos literales al Implico el tipo ellos mismos o tienen su tipo restringido por el tipo esperado de una función de orden superior a la que se están transfiriendo.

Ha habido varias preguntas sobre SO sobre la diferencia entre funciones y métodos que sería una buena lectura de fondo, pero tal vez echar un vistazo a la versión gratuita del libro de Martin Odersky Programming in Scala (Version 1) sería un punto de partida mucho mejor para leer sobre funciones y métodos.

+0

Gracias, Don. Su respuesta es genial al mostrarme algunos literales de funciones. Pero estoy más interesado cuando usará "type Set = Int => Boolean". Esta gramática se ve genial y especial en lenguaje funcional. Me interesaba principalmente cómo usarlo en el caso correcto, no solo usarlo para aprenderlo. –

+0

Como se explicó en @agilesteel, la palabra clave type se usa para proporcionar un alias a un tipo. Donde se vuelve valioso es cuando el tipo con alias es complejo y, por lo tanto, engorroso de usar en declaraciones y el alias conduce a expresiones más compactas y/o intuitivas, por ejemplo tipo PF = PartialFunction [Int, Int] o tipo Position = Tuple2 [Int, Int] –

+0

Sí. Estoy claro con eso. Y lo que he probado println (classOf [Set]) imprime "interface scala.Function1". Y abrí Function1, se define como un rasgo. Entonces, ¿es solo un tipo de rasgo? que es realmente interesante –

0

Estoy considerando algo así. La definición de función en el tipo es abstracta, lo que permite definir diferentes métodos concretos para implementarlos. Creo que se llama polimorfismo o unión posterior. que permite enlazar el tipo de función y el método concreto más adelante en el tiempo de ejecución.

Creo que en JAVA, no puede anular un método abstracto por método estático. Pero en lenguaje funcional, parece muy natural definir un método concreto para implementar la función abstracta. Por favor, corríjame si estoy equivocado.

Mira esto sobre "funciones polimórficas".

http://gleichmann.wordpress.com/2011/01/23/functional-java-polymorphic-functions/

Pero la conclusión es triste para mí. Solo podemos simularlo en Scala. Mira esto desde el enlace.

"Vaya, qué viaje. Vimos que no es posible definir directamente las funciones polimórficas en Scala. En cambio, hay algunas soluciones para simularlas. Todo se reduce al hecho de que una función es el valor de un determinado tipo de Función, que necesita ser parametrizado en el tiempo de ejecución, es decir, todos los parámetros de tipo deben ser parametrizados para obtener un valor real (o instancia de ese tipo) ".

"Por lo tanto, como última conclusión, la definición de funciones polimórficas es posible, pero las consecuencias pueden exceder los beneficios. Como siempre, debe ser consciente de los riesgos dados y decidir por sí mismo si vale la pena las compensaciones (que espero haberte mostrado) para tu área problemática concreta ... "

Cuestiones relacionadas