import cats._
trait Sym[F[_]] {
def lit[A]: A => F[A] // pure
def app[A, B]: F[A => B] => F[A] => F[B] // ap
def lam[A, B]: (F[A] => F[B]) => F[A => B] // coap?
}
implicit def symm[F[_] : Bimonad]: Sym[F] =
new Sym[F] {
val M = Bimonad[F]
def lit[A] = M.pure[A]
def app[A, B] = M.ap[A, B]
def lam[A, B] = f =>
M.pure[A => B](a =>
M.extract(f(M.pure(a))))
}
val PLUS = ((_: Int) + (_: Int)).curried
def answer[F[_] : Sym]: F[Int => Int] = {
val sym = implicitly[Sym[F]]
import sym._
lam(x => app(app(lit(PLUS))(x))(x))
}
no subject
no subject
Уровень абстракции повышается :) я немного позже добавлю пояснения какие-то
no subject
я оттуда экстрагировал идею по абстракции лямбда-исчисления на основе классов типов
получается что в классе типов для абстракции лямбда исчисления необходимо и достаточно чтобы были три операции (не считая fix для рекурсии - это пока отдельная еще тема): литералы-константы, лямбда-абстракция и лямбда-применение.
что интересно - операция конструировая литералов в точности соответсвует pure, операция лямбда-применения в точности соответсвует ap
а вот операция конструированя лямбда-абстракции интересная - она выглядит как дуальная (обратная) к лямбда-применению, то есть к ap (поэтому я ее назвал предположительно coap)
и вот сложность пока возникает именно на операции конструирования-лямбда абстракции
то есть вообще какбы возникает такой определенный теоретический вопрос о такой сущности как дуальность к аппликативу (по аналогии с комонадой - если существуют комонады то должно быть и чтото коаппликативное?)
этот вопрос возник не на пустом какбы месте а по необходимости - вот у нас есть лямбда-применение которое мы знаем как аппликативность функтора, а лямбда-абстракция это в точности обратная операция - где у нас для этого случая есть чтото подходящее? как вообще такую операцию реализовать в общем случае (для лямбда-применение у нас уже есть хорошая подходящая абстракция аппликативного функтора - тут тоже получается нужна еще обратная к нему такая же).
идея главная вообще в том чтобы построить лямбда-исчисления в некотором функторе (как минимум, вообще пока получается что там еще нужна комонада - именно для конструирования лямбда-абстракций)
если у нас будет существовать функтор для лямбда-исчисления мы дальше сможем делать с этим очень интересные вещи типа частичной интерпретации (что позволит реализовать некоторую оптимизирующую компиляцию например в SKI)
вкратце както так) это я вчера еще только первый день как взялся за эту проблему - пока что это некоторый такой промежуточный еще вариант, не окончательный пока еще - ну как и все что я тут пока еще делаю на досуге :)
no subject
no subject
no subject
монада (точнее нам нужен аппликатив но нам еще нужна и комонада - коаппликативов у нас пока еще какбы нет) нам нужна для создания значений-литералов и для лямбда-применений
комонада же (точнее тут я так понимаю есть более общая конструкция которую я пока условно назову коаппликатив) нужна для создания лямбда-абстракций и для получения собственно результата вычислений (то есть extract - который наверное можно считать copure? )
или я чего нибудь пока еще не вижу?
no subject
final tagless это передовая работа, которая недооценена, о ней надо на каждом углу писать.
no subject
наверное дело в том что сопряжение это когда две вообще разные монады? ну тогда вроде бы понятно в чем разница)
ну вот пишу о безтеговости :) и пытаюсь применять ...
no subject
no subject
я вот смотрел тоже у Олега в первоисточниках и там у него тоже получается (в неявном конечно виде) необходима какбы комонада - то есть необходимо иметь возможность распаковать структуру данных
меня в данном случае интересует именно вариант уровня абстракции для такой операции - получается (по крайней мере в cats это так) что extract есть только в интерфейсе Comonad
с другой стороны сама сигнатура типов для lam очень подозрительно (в хорошем смысле) похожа на аппликативное применение в функторе - с точностью только до наоборот )) и вот интересно почему нигде нет еще в стандартных категорных интерфейсах ничего похожего? можно конечно это изготовить из комонады но может быть проще было бы непосредственно такую операцию иметь в арсенале? вот в данном случае она очень была бы к месту...
еще может быть можно както иначе реализовать такую функцию? я имею ввиду (F[A] => F[B]) => F[A => B] которая в lam у меня определена
no subject
no subject
ну вот бимонада вроде как может удовлетворять)
но вобще я бы это назвал как нибудь типа коаппликатива и операции бы назвал copoint и coap
но наверное и бимонада подойдет))
no subject
no subject
no subject
http://mathoverflow.net/questions/254246/when-is-a-container-frobenius
no subject
F[A] => F[B] ~ F[A => B]
концепция комонад и даже бимонад у нас уже в принципе есть в более менее стандартной библиотеке
а вот по поводу изоморфизмов на уровне аппликативности пока чтото ничего не было :)
моя гипотеза в том что такой изоморфизм можно построить с помощью свободного аппликативного функтора
в принципе это даже будет логично))
no subject
вобщем очевидно что это интересный случай получается :)
в принципе наверное пока так можно оставить уже для начала .. потом можно будет както формализовать)
no subject
no subject
no subject
у них там вопрос такой
Are there any interesting implementations of Cotraversable?
instance (Functor c) => Cotraversable c where
cosequence :: (f a -> b) -> (f (c a) -> c b)
а у меня вопрос немного другой (имхо более интересный даже)
(f a -> f b) -> f (a -> b)