Как использовать тип функции в Scala в рамках определенного в типе значения? - PullRequest
10 голосов
/ 11 сентября 2011

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

type Set = Int => Boolean 

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

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

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

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

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

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

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

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

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

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

Правильно ли я понимаю?

Дайте мне знать, почему этот вопрос не ясен или плох, поэтому я могу его улучшить, сэр!

Ответы [ 3 ]

29 голосов
/ 11 сентября 2011

Ключевое слово 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
}

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

1 голос
/ 11 сентября 2011

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

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) быть намного лучшей отправной точкой для чтения о функциях и методах.

0 голосов
/ 16 сентября 2011

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...