scala kittens - applicative
Jun. 11th, 2012 10:36 pmну, посмотрел на scala kittens. чёртов git ещё не сдаётся.
предлагаю правку 1:
теперь не нужно вводить implicit def as
правка 2:
в связи с избытком <*> - у каждого функтора по одному - нужно иметь возможность отличить, какой из нескольких функторов применить в данном месте. (например, в одном из постов ivan_gandhi нужно изобразить что-то вроде Stream.pure(Option.pure(f) Option.<*> _) Stream.<*> _). Нужно ли будет где-то смешивать AppStream.<*> и ZapStream.<*>? Вот на этот вопрос и отвечает следующее рац предложение
Итак, нужен только один класс с <*>, но заворачиваем в Wrapper, чтобы для использования "нужного" ap unwrap соответствующим object.
Пожелания? Комменты?
предлагаю правку 1:
trait Functor[T[_]] {
type f0[A]=T[A] // type f0[_]=T[_] means f0[something] is T[anything]
def f1[A,B](f:A=>B): f0[A] => f0[B]
}теперь не нужно вводить implicit def as
правка 2:
в связи с избытком <*> - у каждого функтора по одному - нужно иметь возможность отличить, какой из нескольких функторов применить в данном месте. (например, в одном из постов ivan_gandhi нужно изобразить что-то вроде Stream.pure(Option.pure(f) Option.<*> _) Stream.<*> _). Нужно ли будет где-то смешивать AppStream.<*> и ZapStream.<*>? Вот на этот вопрос и отвечает следующее рац предложение
class IsFunction[A,B]
implicit def isFunction[X,Y] = new IsFunction[X=>Y,X]
class Wrapper[T[_],A]( val fs: T[A] ) {
def <*>[U[_] <: T[_], X](xs: U[X])(implicit fun:IsFunction[A,X]) = (fs, xs)
}
implicit def wrapper[T[_],A]( x: T[A] ) = new Wrapper[T,A]( x )
trait Applicative[T[_]] extends Functor[T] { // adding applicative to functor
implicit def apply[A,B]( w: Pair[f0[A=>B], f0[A]] ): f0[B] = ap[A,B](w._1)(w._2)
override def f1[A,B](f:A=>B): f0[A]=>f0[B] = pure(f) <*> _
def pure[A](a:A):f0[A]
def ap[A,B](fs: f0[A=>B]): f0[A] => f0[B]
}
implicit object AppSeq extends Applicative[Seq] {
override def pure[A](a:A) = Seq(a)
override def ap[A,B](fs: f0[A=>B]): f0[A] => f0[B] = (as:f0[A]) => fs.flatMap(f => as.map(f) )
}
implicit object ZapSeq extends Applicative[Seq] {
override def pure[A](a:A) = Stream.const(a)
override def ap[A,B](fs: f0[A=>B]): f0[A] => f0[B] = (as:f0[A]) => fs zip as map (f => f._1(f._2) )
}
import AppSeq._
def pp(i: Int) = (j:Int) => i + j*j
println(ap[Int, Int](List(pp(1), pp(2)))(List(10,20,30)))
val v:Seq[Int] = pure(pp(2)) <*> Seq(10,20,30) // implicit apply of AppSeq
println(v)
println(ZapSeq(Seq(pp(1), pp(2)) <*> Seq(10,20,30))) // explicit apply of ZapSeq
// println(AppSeq(Seq(2) <*> Seq(10,20,30))) // -- shouldn't compile(это набросок; тут ещё с вариантостью типов Wrapper нужно разобраться)Итак, нужен только один класс с <*>, но заворачиваем в Wrapper, чтобы для использования "нужного" ap unwrap соответствующим object.
Пожелания? Комменты?
no subject
Date: 2012-06-11 11:22 pm (UTC)P.S. Не всё так просто. Не компилируется; надо разбираться. Идеи-то правильные, но надо разбираться.