Skip to content

Latest commit

 

History

History
147 lines (98 loc) · 5.46 KB

pattern-matching-and-functional-composition.textile

File metadata and controls

147 lines (98 loc) · 5.46 KB
prev next title layout
collections.textile
type-basics.textile
Сопоставление с образцом и функкциональная композиция
post

В этом уроке вы узнаете:

Объединение функций

Давайте создадим две полезные функции:

scala> def addUmm(x: String) = x + " umm"
addUmm: (x: String)String

scala>  def addAhem(x: String) = x + " ahem"
addAhem: (x: String)String

compose

compose создает новую функцию, которая является объединением других функций f(g(x))

scala> val ummThenAhem = addAhem _ compose addUmm _
ummThenAhem: (String) => String = <function1>

scala> ummThenAhem("well")
res0: String = well umm ahem

andThen

andThen похожа на compose, но сначала вызывается первая функция, затем вторая g(f(x))

scala> val ahemThenUmm = addAhem _ andThen addUmm _
ahemThenUmm: (String) => String = <function1>

scala> ahemThenUmm("well")
res1: String = well ahem umm

Каррирование и Частичный вызов функций

case утверждения

Что же такое case утверждения?

Это подкласс функций, который называется PartialFunction.

Что представляет собой сов��купность множества case утверждений?

Это множество объединений PartialFunctions вместе.

Понимание PartialFunction

Функция работает для каждого аргумента определенного типа. Другими словами, функция объявляется как (Int) => String, принимающая любой Int и возвращающая строку.

Частичная функция определена только для определенных значений определенного типа. Частичные функции (Int) => String не может принимать любой Int.

isDefinedAt это метод PartialFunction, который может использоваться, чтобы определить, будет ли PartialFunction принимать данный аргумент.

Заметьте PartialFunction не связана с частично вызываемыми функциями, о которых мы говорили ранее.

Смотрите также: В Effective Scala описывается PartialFunction.

scala> val one: PartialFunction[Int, String] = { case 1 => "one" }
one: PartialFunction[Int,String] = <function1>

scala> one.isDefinedAt(1)
res0: Boolean = true

scala> one.isDefinedAt(2)
res1: Boolean = false

Вы можете использовать частичную функцию.

scala> one(1)
res2: String = one

PartialFunctions может быть объединена с чем-то новым, называемым OrElse, который показывает, определен ли PartialFunction с передаваемым аргументом.

scala> val two: PartialFunction[Int, String] = { case 2 => "two" }
two: PartialFunction[Int,String] = <function1>

scala> val three: PartialFunction[Int, String] = { case 3 => "three" }
three: PartialFunction[Int,String] = <function1>

scala> val wildcard: PartialFunction[Int, String] = { case _ => "something else" }
wildcard: PartialFunction[Int,String] = <function1>

scala> val partial = one orElse two orElse three orElse wildcard
partial: PartialFunction[Int,String] = <function1>

scala> partial(5)
res24: String = something else

scala> partial(3)
res25: String = three

scala> partial(2)
res26: String = two

scala> partial(1)
res27: String = one

scala> partial(0)
res28: String = something else

Тайна о case.

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

scala> case class PhoneExt(name: String, ext: Int)
defined class PhoneExt

scala> val extensions = List(PhoneExt("steve", 100), PhoneExt("robey", 200))
extensions: List[PhoneExt] = List(PhoneExt(steve,100), PhoneExt(robey,200))

scala> extensions.filter { case PhoneExt(name, extension) => extension < 200 }
res0: List[PhoneExt] = List(PhoneExt(steve,100))

Почему это работает?

filter принимает функцию. В этом случае используется функция-предикат (PhoneExt) => Boolean.

PartialFunction – это подтип Function, поэтому filter может принимать PartialFunction в качестве аргумента!