Created
December 12, 2011 02:22
-
-
Save gakuzzzz/1464359 to your computer and use it in GitHub Desktop.
型クラスを使わないMonadic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Functor[+A, M[A] <: Functor[A, M]] { | |
def map[B](f: A => B): M[B] | |
def fmap[B] = map[B] _ | |
} | |
trait Pointed[M[_] <: Pointed[M]] { | |
def pure[A](a: A): M[A] | |
} | |
trait Applicative[+A, M[A] <: Applicative[A, M]] extends Functor[A, M] with Pointed[M] { | |
def <*>[B >: A, C](fm: M[B => C]): M[C] | |
def <*>:[B >: A, C] = <*>[B, C] _ | |
def map[B](f: A => B): M[B] = this <*> pure(f) | |
def `<$>`[B] = map[B] _ | |
def `<$>:`[B] = map[B] _ | |
} | |
trait Monad[+A, M[A] <: Monad[A, M]] extends Applicative[A, M] { | |
def flatMap[B](f: A => M[B]): M[B] | |
def >>=[B] = flatMap[B] _ | |
def `return`[B] = pure[B] _ | |
def <*>[B >: A, C](fm: M[B => C]): M[C] = | |
fm flatMap {f => this flatMap {v => pure(f(v))}} | |
// fm >>= {f => this >>= {v => `return`(f(v))}} | |
} | |
trait Semigroup0[M <: Semigroup0[M]] { | |
def append(a: M): M | |
} | |
trait Semigroup1[+A, M[A] <: Semigroup1[A, M]] { | |
def append[B >: A](a: M[B]): M[B] | |
} | |
trait Monoid0[M <: Monoid0[M]] extends Semigroup0[M] { | |
def zero: M | |
} | |
trait Monoid1[+A, M[A] <: Monoid1[A, M]] extends Semigroup1[A, M] { | |
def zero[B >: A]: M[B] | |
} | |
trait MonadPlus[+A, M[A] <: MonadPlus[A, M]] extends Monad[A, M] with Monoid1[A, M] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed trait Maybe[+A] extends MonadPlus[A, Maybe] { | |
def pure[B](b: B): Maybe[B] = if (b == null) Not else Just(b) | |
def zero[B >: A]: Maybe[B] = Not | |
} | |
case class Just[+A](value: A) extends Maybe[A] { | |
def flatMap[B](f: A => Maybe[B]): Maybe[B] = f(value) | |
def append[B >: A](a: Maybe[B]): Maybe[B] = this | |
} | |
case object Not extends Maybe[Nothing] { | |
def flatMap[B](f: Nothing => Maybe[B]): Maybe[B] = Not | |
def append[B >: Nothing](a: Maybe[B]): Maybe[B] = a | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed trait Cons[+A] extends MonadPlus[A, Cons] { | |
def ::[B >: A](b: B): Cons[B] = Cell(b, this) | |
def pure[B](b: B): Cons[B] = b :: Empty | |
def ++[B >: A] = append[B] _ | |
def append[B >: A](a: Cons[B]): Cons[B] | |
def zero[B >: A]: Cons[B] = Empty | |
} | |
case class Cell[+A](head: A, tail: Cons[A]) extends Cons[A] { | |
def flatMap[B](f: A => Cons[B]): Cons[B] = f(head) ++ (tail flatMap f) | |
def append[B >: A](a: Cons[B]): Cons[B] = head :: tail ++ a | |
} | |
case object Empty extends Cons[Nothing] { | |
def flatMap[B](f: Nothing => Cons[B]): Cons[B] = Empty | |
def append[B >: Nothing](a: Cons[B]): Cons[B] = a | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed trait Ordering extends Monoid0[Ordering] { | |
def zero: Ordering = EQ | |
} | |
case object LT extends Ordering { | |
def append(a: Ordering): Ordering = this | |
} | |
case object EQ extends Ordering { | |
def append(a: Ordering): Ordering = a | |
} | |
case object GT extends Ordering { | |
def append(a: Ordering): Ordering = this | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scala> for { | |
| a <- Just("aaa") | |
| b <- Just("bbb") | |
| } yield a + b | |
res0: Maybe[java.lang.String] = Just(aaabbb) | |
scala> for { | |
| a <- Just("aaa") | |
| n <- Not | |
| b <- Just("bbb") | |
| } yield a + n + b | |
res1: Maybe[java.lang.String] = Not | |
scala> (1 :: 2 :: 3 :: Empty) `<$>` (2 + _) | |
res2: Cons[Int] = Cell(3,Cell(4,Cell(5,Empty))) | |
scala> val ff: (Int, Int, Int) => Int = _ + _ + _ | |
ff: (Int, Int, Int) => Int = <function3> | |
scala> ((ff.curried `<$>:` Just(10)) <*>: Just(20)) <*>: Just(30) | |
res3: Maybe[Int] = Just(60) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment