Как использовать тип функции в scala в пределах определенного типа значимо?

Я новичок и наивна к scala. Просто знайте, как определить тип функции, например Set здесь (только в качестве примера).

type Set = Int => Boolean 

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

Я также прочитал wiki типа агностики языка. Кажется, С#, C, Haskel также имеют аналогичный грамматик. http://en.wikipedia.org/wiki/Function_type.

Мой вопрос в том, в каком случае вы предпочитаете определять одну из таких функций абстрактного типа и использовать его, И нет другого выбора для достижения той же цели? Сравнивая непосредственно с конкретным методом с помощью def

Или я могу потерять это требование, чтобы сказать, используя этот тип функции, я могу сделать код намного лучше. Чтобы я мог узнать больше о типе функции.

Здесь моя главная интересующая часть type Set = Int => Boolean, когда вы хотите ее абстрагировать? Я ищу случай использования в реальной жизни и как реализовать его в конкретном методе в грамматике scala. Например, это немного сложнее.

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

Я знаю, что это называется более высокосортными типами. Сам грамматик действительно имеет смысл. Но мне просто нужны более простые примеры реальной жизни для начинающих scala.

Я нашел этот ответ, описывающий его. Что такое более высокий тип в Scala?

Но это все еще выглядит немного неясным для меня. Я предпочитаю простой ответ для новичка. Похоже, что сама функция не требовала ничего, кроме параметра и типа результата, для реализации mentod. Например, если результат (Boolean) не исходит из параметра (Int), он все еще компилируется.

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

Неужели я не прав?

Сообщите мне, почему этот вопрос не ясен или плох, поэтому я могу его улучшить, сэр!

Ответ 1

Ключевое слово type в Scala создает псевдоним для заданного типа. Например:

scala> type Str = String
defined type alias Str

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

Это очень похоже на то, что вы сделали:

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

Хотя псевдонимы типов иногда могут быть полезны для разъяснения, документация не является их основным вариантом использования. Система типа Scala очень сложна. Например, существует альтернатива дженерикам, а именно абстрактным типам. Рассмотрим это:

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

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

Эти примеры кода в основном выполняют одно и то же, но бывают ситуации, когда вам нужны абстрактные типы, но не могут (или не должны) использовать дженерики. Вы можете найти более подробную информацию здесь.

Ответ 2

Вы можете определить литерал функции следующим образом:

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

или если у вас есть какой-то контекст, который можно использовать для вывода типа Scala, вы можете использовать приведенные формы, например:

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

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

или даже

listOfInt map {1 +}

Все эти литералы подразумевают сам тип или имеют свой тип, ограниченный ожидаемым типом функции более высокого порядка, к которой они передаются.

Было задано несколько вопросов о SO о различии между функциями и методами, которые были бы хорошими исходными текстами, но, возможно, взглянув на бесплатную версию книги Мартина Одерского Программирование в Scala (версия 1) стало бы намного лучшей отправной точкой для ознакомления с функциями и методами.

Ответ 3

Я так думаю. Определение функции в типе является абстрактным, что позволяет определять различные конкретные методы для их реализации. Я думаю, что это называется полиморфизмом или позднее обязательным. что позволяет связать тип функции и конкретный метод позже во время выполнения.

Я думаю, что в JAVA вы не можете переопределить абстрактный метод статическим методом. Но в функциональном языке кажется очень естественным определить конкретный метод реализации абстрактной функции. Пожалуйста, поправьте меня, если я ошибаюсь.

Посмотрите на это о "полиморфных функциях".

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

Но мне грустный вывод. Мы можем только имитировать его в scala. Проверьте это по ссылке.

"Ничего себе, какое путешествие. Мы увидели, что невозможно определить полиморфные функции в scala. Вместо этого существуют некоторые способы их моделирования. Все сводится к тому, что функция значение определенного типа функции, которое должно быть параметризировано по типу во время выполнения, то есть все параметры типа должны быть параметризованы по типу для получения реального значения (или экземпляра этого типа).

"Итак, как последний вывод, определение полиморфных функций возможно, но последствия могут привести к снижению веса. Как всегда, вы должны знать об этих рисках и сами решать, стоит ли компромисс (что я надеюсь чтобы показать вам) для вашей конкретной проблемной области..."