Mar. 10th, 2012

juan_gandhi: (Default)
Когда снится, что я бегаю по 13-й линии с мелкокалиберным пулемётом, стреляю, но ведёт влево и вверх, как АК-47... Вообще Васин снится аномально часто.

Но я не о том, а о волнах, гасящих ветер.

Мало что поливальная труба из-под земли бьёт фонтаном, и что кроссовка с тренажера развалилась почти, а в обувной тащиться жутко лень (так что утром приклеил и струбциной зажал - но вечером тренажер скипнул чисто по-разгильдяйски).

Вчера прихожу домой, гаражная дверь не открывается. А от нормальной двери у меня ключей что-то нету. А то место, где мы раньше хранили на улице запасной ключ, мы там что-то попереворошили, короче, ключа нету. Ходил в темноте вокруг дома дёргал все двери и окна.

Потом подкатил мусорный бак к гаражной двери, снял куртку, отогнул верхний угол двери и туда просклизнул с трудом, по кошачьему и новорожденческому принципу "голова пролезла, остальное пройдёт".

Сегодня звонил Саркису, придут починять в 4, так что велик опять обломился. Ну завтра, под дождём поеду. Сейчас-то надо про аппликативы писать (и гори всё остальное огнём, тьфу-тьфу, не в буквальном смысле).

А так-то всё хорошо. Время от времени только спрашиваю себя, почему я последние года три потратил на работу с идиотами? Как вспомню всех этих людей, так вздрогну. Главное, когда я там был, относился ко всему как-то более снисходительно. А зря. Грубо говоря, видишь монаду - называй её монадой. Как Солженицын учил.
juan_gandhi: (Default)
1, 2, 3, 4, 5, 6, 7, 8, 9, 10

В предыдущей серии мы познакомились с аппликативным функтором.

Чем эти аппликативные функторы хороши - тем, что композиция двух аппликативных функторов - аппликативный функтор. Вот возьмём


def process (user: User) (phone:Phone) = { val s = user.name + ": " + phone.number; println(s); s }
val result: Set[String] = AppSet.pure(process) <*> db.getUser(userId) <*> db.getPhones(userId)


и представим, что db.getSomething(userId) возвращает не Set[Something], а Future[Set[Something]] - обещание вернуть что-то, когда готово будет. Тогда и результат наш будет иметь форму


val result: Future[Set[String]] = AppFuture.pure(AppSet.pure(process)) <*> db.getUser(userId) <*> db.getPhones(userId)


Тут немножко неуклюже выглядит вызов двух pure AppFuture.pure(AppSet.pure(process)); но на это в скале есть неявные функции. Если мы определим

implicit def singleton[T](t: T) = AppSet.pure(t)
implicit def toFuture[T](t: T) = AppFuture.pure(t)


то можно переписать наш код красивее:


val result = process <*> db.getUser(userId) <*> db.getPhones(userId)


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

Чтобы функтор был аппликативным, мы должны были определить

  def ap[A, B](f: F[A => B], a: F[A]): F[B]


Для монады, грубо говоря, это преобразование строится автоматически, а в общем случае его где-то надо достать. Альтернативно, можно иметь

  def strength[A, B](F[A], F[B]): F[A × B]


A × B - такого обозначения в Скале нету на самом деле; есть
Pair[A, B], aka Tuple2[A, B] - класс пар; ну мы ж все понимаем, что это декартово произведение и есть, и формально надо было написать

  def strength[A, B](Pair[F[A], F[B]]): F[Pair[A, B]]


Откуда такая эквивалентность?

Если есть strength, то можно определить


  def ap[A, B](ff: F[A => B], fa: F[A]): F[B] = strength(ff, fa).map((f, a) => f(a))


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

Ну и наоборот, если есть аппликативность ap, определим


  def pairing[A, B](a: A): (B => Pair[A, B]) = b => (a, b) // функция такая
  def pairingLifted[A, B](fa: F[A]): (F[B] => F[Pair[A, B]]) = fa map pairing // та же функция, да на F[A]
  def strength[A, B](fa: F[A], fb: F[B]): F[Pair[A, B]] = ap(pairingLifted, fa) // QED


Мы тут, можно сказать, теорему доказали; спасибо [livejournal.com profile] akuklev, подсказал.

Вот эта сила, strentgh, традиционно называется монадической силой, если речь идёт о монадах. И в компьютерной науке есть поверие, что всякая монада обладает монадической силой - ну просто мы подымем бинарную операцию в монаду, и всё получится.

Вообще говоря, в математике не всякая монада сильна; но об этом, наверное, в следующий раз, с детальным примером.

juan_gandhi: (Default)
Сел примерно в 4 часа. И вот закончил, осталось зафайлить. Ну это на свежую голову наадо.

У меня ж непростая ситуация.

Четыре W2, три 1099, какие-то иностранные налоги, какие-то К1, дескать партнёром где-то был; откаты за прошлые переплаты налогов и потери на стоках (это ещё с гугловских времён), скидки за проценты по моргиджу, и т.д. и т.п.

За дом плачу примерно 1200 в месяц, это проценты и плюс-минус налоги.

Система опять мне должна почти 10к.

Но как турботакс работает классно! Восторг. Лучшая веб-аппликация на планете.
juan_gandhi: (Default)
Что израильская военщина не кого попало обстреливает, а аккуратно тех интересных людей, что Шалита захватили.

Респект.

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

August 2025

S M T W T F S
      12
3456789
10 11 12 13141516
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 16th, 2025 03:12 pm
Powered by Dreamwidth Studios