@lyrical_logical
trait UserProfile {
def name: String
def age: Int
}
trait UserStatus {
def name: String
def stamina: Int
}
trait UserProfile {
def name: String
def age: Int
}
trait UserStatus {
def name: String
def stamina: Int
}
trait User {
def name: String
}
trait UserProfile extends User {
def age: Int
}
trait UserStatus extends User {
def stamina: Int
}
単なる例なので正規化とか composition とか無視
sealed trait IntList
case object IntNil extends IntList
case class IntCase(head: Int, tail: IntList) extends IntList
def sum(list: IntList): Int = list match {
case IntNil => 0
case IntCons(head, tail) => head + sum(tail)
}
def product(list: IntList): Int = list match {
case IntNil => 1
case IntCons(head, tail) => head * product0(tail)
}
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
def sum(list: IntList): Int = list match {
case IntNil => 0
case IntCons(head, tail) => head + sum(tail)
}
def product(list: IntList): Int = list match {
case IntNil => 1
case IntCons(head, tail) => head * product0(tail)
}
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
def fold[T](list: IntList, t: T)(f: (Int, T) => T): T = {
list match {
case IntNil => t
case IntCons(head, tail) => f(head, fold(tail, t)(f))
}
}
def sum(list: IntList): Int = fold(list, 0) { _ + _ }
def prod(list: IntList): Int = fold(list, 1) { _ * _ }
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
sealed trait IntTree
case object IntLeaf extends IntTree
case class IntNode(value: Int, left: IntTree, right: IntTree)
extends IntTree
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
sealed trait IntTree
case object IntLeaf extends IntTree
case class IntNode(value: Int, left: IntTree, right: IntTree)
extends IntTree
sealed trait ListLike[F[+_]]
case object LikeNil extends ListLike[Nothing]
case class LikeCons[F[+_]](out: F[ListLike[F]])
extends ListLike[F]
type IntList =
ListLike[ ({ type apply[+T] = (Int, T) })#apply ]
type IntTree =
ListLike[ ({ type apply[+T] = (Int, T, T) })#apply }
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
sealed trait IntTree
case object IntLeaf extends IntTree
case class IntNode(value: Int, left: IntTree, right: IntTree)
extends IntTree
case class IntRoseTree(children: Seq[IntRoseTree])
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
sealed trait IntTree
case object IntLeaf extends IntTree
case class IntNode(value: Int, left: IntTree, right: IntTree)
extends IntTree
case class IntRoseTree(children: Seq[IntRoseTree])
Nil, Leaf 相当が無い!
sealed trait IntList
case object IntNil extends IntList
case class IntCons(head: Int, tail: IntList) extends IntList
sealed trait IntTree
case object IntLeaf extends IntTree
case class IntNode(value: Int, left: IntTree, right: IntTree)
extends IntTree
case class IntRoseTree(children: Seq[IntRoseTree])
case class Infinite(self: Infinite)
使い道 is ない
case class Mu[F[+_]](in: F[Mu[F]])
構造に「遊び」を作る
F
Cons
μ
F
Node
F
RoseTree
F
Nil, Leaf
μ……
μ
μ
sealed trait IntListF[+T]
case object IntNilF extends IntListF[Nothing]
case class IntConsF[+T](head: Int, tail: T) extends IntListF[T]
type IntList = Mu[IntListF]
def nil = Mu[IntListF](IntNilF)
def cons(head: Int, tail: Mu[IntListF]) =
Mu[IntListF](IntConsF(head, tail))
val nums: IntList = cons(1, cons(2, nil))
F
Cons
μ
F
Nil
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
def reduce[T, F[+_]](mu: Mu[F])(f: F[T] => T)
(implicit ev: Functor[F]): T =
{
f(ev.map(mu.in)(reduce[T, F](_)(f)))
}
Functor を経由して再帰的に処理
implicit object intListFunctor extends Functor[IntListF] {
def map[A, B](fa: IntListF[A])(f: A => B): IntListF[B] = {
fa match {
case IntNilF => IntNilF
case IntConsF(head, tail) => IntConsF(head, f(tail))
}
}
}
Functor を経由した再帰呼び出し
def fold[T](list: IntList, t: T)(f: (Int, T) => T): T = {
reduce(list)({
case IntNilF => t
case IntConsF(head, tail) => f(head, tail)
}: IntListF[T] => T)
}
def sum(list: IntList): Int = fold(intList, 0) { _ + _ }
def prod(list: IntList): Int = fold(intList, 1) { _ * _ }
case class Mu[F[+_, +_], +A](in: F[A, Mu[F, A]])
// non parametric version
// case class Mu[F[+_]](in: F[Mu[F]])
sealed trait ListF[+A, +B]
case object NilF extends ListF[Nothing, Nothing]
case class ConsF[+A, +B](head: A, tail: B) extends ListF[A, B]
type List[+A] = Mu[ListF, A]
def nil = Mu[ListF, Nothing](NilF)
def cons[A](head: A, tail: Mu[ListF, A]) = Mu(ConsF(head, tail))
val intList: List[Int] = cons(1, cons(2, nil))
val stringList: List[String] = cons("a", cons("b", nil))
trait BiFunctor[F[_, _]] {
def bimap[A, B, C, D](fab: F[A, B])
(f: A => C)
(g: B => D): F[C, D]
}
trait BiFunctor[F[_, _]] {
def bimap[A, B, C, D](fab: F[A, B])
(f: A => C)
(g: B => D): F[C, D]
}
def reduce[A, B, F[+_, +_]](mu: Mu[F, A])(f: F[A, B] => B)
(implicit ev: BiFunctor[F]): B =
{
f(ev.bimap(mu.in)(identity)(reduce(_)(f)))
}
implicit object listBiFunctor extends BiFunctor[ListF] {
def bimap[A, B, C, D](fab: ListF[A, B])
(f: A => C)
(g: B => D): ListF[C, D] = {
fab match {
case NilF => NilF
case ConsF(head, tail) => ConsF(f(head), g(tail))
}
}
}
BiFunctor を経由した再帰呼び出し
def fold[A, B](list: List[A], t: B)(f: (A, B) => B): B = {
reduce(list)({
case NilF => t
case ConsF(head, tail) => f(head, tail)
}: ListF[A, B] => B)
}
def sum(list: List[Int]): Int = fold(list, 0) { _ + _ }
def prod(list: List[Int]): Int = fold(list, 1) { _ + _ }
case class Mu[F[+_, +_], +A](in: F[A, Mu[F, A]])
sealed trait Mu[F[+_, +_], +A]
case class End[[F+_, +_], +A](a: A) extends Mu[F, A]
case class In[F[+_, +_], +A](in: F[A, Mu[F, A]])
extends Mu[F, A]
// ListLike っぽいですね
sealed trait Mu[F[+_], +A]
case class End[F[+_], +A](a: A) extends Mu[F, A]
case class In[F[+_], +A](in: F[Mu[F, A]])
extends Mu[F, A]
// 最初にでてきたμ operator っぽいですね
sealed trait Free[F[+_], +A]
case class Pure[F[+_], +A](a: A) extends Free[F, A]
case class Suspend[F[+_], +A](f: F[Free[F, A]])
extends Free[F, A]
@lyrical_logical
@lyrical_logical