Pull to refresh

Comments 11

def lift[A, B](f: A => B): F[A] => F[B] = map(_)(f)

И эти люди ругали COBOL...

Это Scala, тут по другому никак, хотите элегантности вам к F#/Haskell/ML, а если типы особо не нужны то Clojure вам подойдет.

COBOL — верх читаемости и понятности по сравнению с этим.

COBOL не работает на таком уровне абстракций. lift — мощный универсальный инструмент, который затруднительно даже представить в слабо-абстрактных языках.

Он настолько универсален, что даже сложно представить, зачем он вообще нужен.

Есть хорошие книги и курсы, с помощью которых можно освоить абстракции, используемые в функциональном программировании. Например, FP in Scala (либо аналогичная книжка на Haskell'e — haskellbook.com). На coursera есть специализация "Functional Programming in Scala".


Ну а собственно lift из обычной функции делает функцию, работающую с какой-то структурой. Например,


val inc: Int => Int = _ + 1
val linc: List[Int] => List[Int] = Functor[List].lift(inc)

val List(11,12,13) = linc(List(10,11,12))

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


def algorithm[F[_]: Functor, A: Numeric](fa: F[A]): F[A] = {
  val N = Numeric[A]
  val F = Functor[F]
  val inc = N.plus(_, N.one)
  val finc = F.lift(inc)
  finc(fa)
}

такой алгоритм будет работать с любыми структурами данных (для которых есть Functor) и любыми числовыми типами (для которых есть Numeric).

UFO just landed and posted this here

Разные цели/задачи — разные языки.


Бизнес-логику вполне можно писать на Scala с помощью подходящего DSL. В том числе, и не столь прямолинейную.
"Премудрости" дают инструменты для хороших библиотек и DSL. На прикладном уровне хорошие библиотеки использовать достаточно легко, и можно в большинстве случаев обходиться поверхностными знаниями, не вникая в детали.
Для некоторых задач отсутствие адекватных по сложности инструментов приводит к тому, что программы получаются не очень хорошими (многословными, с повторами похожего кода, с необходимостью заново тестировать похожую функциональность).

Ради уточнения. Вы понимаете смысл этого кода и считаете что он плохо выглядит или не понимаете и поэтому считаете что он плохо выглядит?

То же самое на Haskell:


lift :: (A -> B) -> F A -> F B
lift f = flip map f

не то, чтобы стало сильно легче...


Видимая сложность функции lift связана с её универсальностью. При использовании, вообще говоря, всё довольно удобно и не выглядит сложным:


val inc: Int => Int = _ + 1
val oinc: Option[Int] => Option[Int] = Option.lift(inc)

val Option(11) = oinc(10.some)
Sign up to leave a comment.