Skip to content

Commit

Permalink
Kleisli.mapK and remove Alternative(Empty)
Browse files Browse the repository at this point in the history
  • Loading branch information
purefn committed Feb 8, 2012
1 parent 37d7d9d commit 42ee545
Show file tree
Hide file tree
Showing 14 changed files with 19 additions and 216 deletions.
33 changes: 0 additions & 33 deletions core/src/main/scala/scalaz/Alternative.scala

This file was deleted.

33 changes: 0 additions & 33 deletions core/src/main/scala/scalaz/AlternativeEmpty.scala

This file was deleted.

30 changes: 10 additions & 20 deletions core/src/main/scala/scalaz/Kleisli.scala
Expand Up @@ -25,8 +25,11 @@ sealed trait Kleisli[M[_], A, B] { self =>

def =<<[AA <: A](a: M[AA])(implicit m: Bind[M]): M[B] = m.bind(a)(run _)

def map[C](f: B => C)(implicit m: Functor[M]): Kleisli[M, A, C] =
kleisli(a => m.map(run(a))(f))
def map[C](f: B => C)(implicit M: Functor[M]): Kleisli[M, A, C] =
kleisli(a => M.map(run(a))(f))

def mapK[N[_], C](f: M[B] => N[C]): Kleisli[N, A, C] =
kleisli(a => f(run(a)))

def flatMapK[C](f: B => M[C])(implicit M: Bind[M]): Kleisli[M, A, C] =
kleisli(a => M.bind(run(a))(f))
Expand Down Expand Up @@ -69,21 +72,21 @@ trait KleisliInstances2 extends KleisliInstances3 {
implicit def F: Applicative[F] = F0
}
implicit def kleisliIdApplicative[R]: Applicative[({type λ[α] = Kleisli[Id, R, α]})#λ] = kleisliApplicative[Id, R]
implicit def kleislPlus[F[_], A](implicit F0: Plus[F]) = new KleisliPlus[F, A] {
implicit def F = F0
}
}

trait KleisliInstances1 extends KleisliInstances2 {
implicit def kleisliAlternative[F[_], R](implicit F0: Alternative[F]): Alternative[({type λ[α] = Kleisli[F, R, α]})#λ] = new KleisliAlternative[F, R] {
implicit def F: Alternative[F] = F0
implicit def kleisliApplicativePlus[F[_], R](implicit F0: ApplicativePlus[F]): ApplicativePlus[({type λ[α] = Kleisli[F, R, α]})#λ] = new ApplicativePlus[({type λ[α] = Kleisli[F, R, α]})#λ] with KleisliApplicative[F, R] with KleisliPlusEmpty[F, R] {
implicit def F: ApplicativePlus[F] = F0
}
implicit def kleisliArrId[F[_]](implicit F0: Pointed[F]) = new KleisliArrIdArr[F] {
implicit def F: Pointed[F] = F0
}
implicit def kleisliSemigroup[F[_], A, B](implicit FB0: Semigroup[F[B]]) = new KleisliSemigroup[F, A, B] {
implicit def FB = FB0
}
implicit def kleislPlus[F[_], A](implicit F0: Plus[F]) = new KleisliPlus[F, A] {
implicit def F = F0
}
}

trait KleisliInstances0 extends KleisliInstances1 {
Expand All @@ -109,9 +112,6 @@ trait KleisliInstances extends KleisliInstances0 {
implicit def kleisliPlusEmpty[F[_], A](implicit F0: PlusEmpty[F]) = new KleisliPlusEmpty[F, A] {
implicit def F = F0
}
implicit def kleisliAlternativeEmpty[F[_], R](implicit F0: AlternativeEmpty[F]): AlternativeEmpty[({type λ[α] = Kleisli[F, R, α]})#λ] = new KleisliAlternativeEmpty[F, R] {
implicit def F: AlternativeEmpty[F] = F0
}
implicit def kleisliMonadTrans[R]: Hoist[({type λ[α[_], β] = Kleisli[α, R, β]})#λ] = new KleisliHoist[R] {}
}

Expand Down Expand Up @@ -163,16 +163,6 @@ private[scalaz] trait KleisliApplicative[F[_], R] extends Applicative[({type λ[
implicit def F: Applicative[F]
}

private[scalaz] trait KleisliAlternative[F[_], R] extends Alternative[({type λ[α] = Kleisli[F, R, α]})#λ] with KleisliApplicative[F, R]{
implicit def F: Alternative[F]
def orElse[A](a: Kleisli[F, R, A], b: => Kleisli[F, R, A]): Kleisli[F, R, A] = Kleisli[F, R, A](r => F.orElse(a(r), b apply r))
}

private[scalaz] trait KleisliAlternativeEmpty[F[_], R] extends AlternativeEmpty[({type λ[α] = Kleisli[F, R, α]})#λ] with KleisliAlternative[F, R] {
implicit def F: AlternativeEmpty[F]
def empty[A]: Kleisli[F, R, A] = Kleisli[F, R, A](r => F.empty)
}

private[scalaz] trait KleisliMonad[F[_], R] extends Monad[({type λ[α] = Kleisli[F, R, α]})#λ] with KleisliApplicative[F, R] {
implicit def F: Monad[F]
def bind[A, B](fa: Kleisli[F, R, A])(f: A => Kleisli[F, R, B]): Kleisli[F, R, B] = fa flatMap f
Expand Down
15 changes: 0 additions & 15 deletions core/src/main/scala/scalaz/OptionT.scala
Expand Up @@ -84,9 +84,6 @@ trait OptionTInstances1 extends OptionTInstances2 {
}

trait OptionTInstances0 extends OptionTInstances1 {
implicit def optionTAlternativeEmpty[F[_]](implicit F0: Monad[F]): AlternativeEmpty[({type λ[α] = OptionT[F, α]})#λ] = new OptionTAlternativeEmpty[F] {
implicit def F: Monad[F] = F0
}
implicit def optionTFoldable[F[_]](implicit F0: Foldable[F]): Foldable[({type λ[α] = OptionT[F, α]})#λ] = new OptionTFoldable[F] {
implicit def F: Foldable[F] = F0
}
Expand Down Expand Up @@ -154,18 +151,6 @@ private[scalaz] trait OptionTTraverse[F[_]] extends Traverse[({type λ[α] = Opt
def traverseImpl[G[_] : Applicative, A, B](fa: OptionT[F, A])(f: (A) => G[B]): G[OptionT[F, B]] = fa traverse f
}

trait OptionTAlternative[F[_]] extends Alternative[({type λ[α] = OptionT[F, α]})#λ] with OptionTApply[F] with OptionTPointed[F] {
implicit def F: Monad[F]

def orElse[A](a: OptionT[F, A], b: => OptionT[F, A]): OptionT[F, A] = a orElse b
}

trait OptionTAlternativeEmpty[F[_]] extends AlternativeEmpty[({type λ[α] = OptionT[F, α]})#λ] with OptionTAlternative[F] {
implicit def F: Monad[F]

def empty[A]: OptionT[F, A] = OptionT(F.point(None))
}

private[scalaz] trait OptionTHoist extends Hoist[OptionT] {
def liftM[G[_], A](a: G[A])(implicit G: Monad[G]): OptionT[G, A] =
OptionT[G, A](G.map[A, Option[A]](a)((a: A) => Some(a)))
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/scalaz/std/List.scala
Expand Up @@ -4,7 +4,7 @@ package std
import annotation.tailrec

trait ListInstances {
implicit val listInstance = new Traverse[List] with MonadPlus[List] with Each[List] with Index[List] with Length[List] with Alternative[List] {
implicit val listInstance = new Traverse[List] with MonadPlus[List] with Each[List] with Index[List] with Length[List] with ApplicativePlus[List] {
def each[A](fa: List[A])(f: (A) => Unit) = fa foreach f
def index[A](fa: List[A], i: Int) = {
var n = 0
Expand Down Expand Up @@ -43,8 +43,6 @@ trait ListInstances {
}
}

def orElse[A](a: List[A], b: => List[A]) = a ++ b

override def traverseS[S,A,B](l: List[A])(f: A => State[S,B]): State[S,List[B]] = {
State((s: S) => {
val buf = new collection.mutable.ListBuffer[B]
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/scala/scalaz/std/Option.scala
Expand Up @@ -8,7 +8,7 @@ trait OptionInstances0 {
}

trait OptionInstances extends OptionInstances0 {
implicit val optionInstance = new Traverse[Option] with MonadPlus[Option] with Each[Option] with Index[Option] with Length[Option] with AlternativeEmpty[Option] {
implicit val optionInstance = new Traverse[Option] with MonadPlus[Option] with Each[Option] with Index[Option] with Length[Option] with ApplicativePlus[Option] {
def point[A](a: => A) = Some(a)
def each[A](fa: Option[A])(f: (A) => Unit) = fa foreach f
def index[A](fa: Option[A], n: Int) = if (n == 0) fa else None
Expand All @@ -30,7 +30,6 @@ trait OptionInstances extends OptionInstances0 {
case Some(a) => f(a, z)
case None => z
}
def orElse[A](a: Option[A], b: => Option[A]) = a orElse b
}

implicit def optionMonoid[A: Semigroup]: Monoid[Option[A]] = new Monoid[Option[A]] {
Expand Down
33 changes: 0 additions & 33 deletions core/src/main/scala/scalaz/syntax/AlternativeEmptySyntax.scala

This file was deleted.

39 changes: 0 additions & 39 deletions core/src/main/scala/scalaz/syntax/AlternativeSyntax.scala

This file was deleted.

6 changes: 1 addition & 5 deletions core/src/main/scala/scalaz/syntax/Syntax.scala
Expand Up @@ -37,10 +37,6 @@ trait Syntaxes {

object applicative extends ToApplicativeV

object alternative extends ToAlternativeV

object alternativeEmpty extends ToAlternativeEmptyV

object bind extends ToBindV

object monad extends ToMonadV
Expand Down Expand Up @@ -95,7 +91,7 @@ trait ToAllTypeClassV
with ToApplicativeV with ToBindV with ToMonadV with ToCoJoinV with ToCoMonadV
with ToPlusV with ToApplicativePlusV with ToMonadPlusV with ToTraverseV with ToBiFunctorV
with ToBiTraverseV with ToArrIdV with ToComposeV with ToCategoryV
with ToArrowV with ToFoldableV with ToAlternativeV with ToAlternativeEmptyV
with ToArrowV with ToFoldableV


trait SyntaxV[A] {
Expand Down
Expand Up @@ -218,29 +218,6 @@ object ScalazProperties {
}
}

object alternative {
def associative[F[_], X](implicit f: Alternative[F], afx: Arbitrary[F[X]], ef: Equal[F[X]]) =
forAll(f.alternativeLaw.associative[X] _)

def laws[F[_]](implicit F: Alternative[F], afx: Arbitrary[F[Int]], ef: Equal[F[Int]]) = new Properties("alternative") {
property("associative") = associative[F, Int]
}
}

object alternativeEmpty {
def leftAlternativeIdentity[F[_], X](implicit f: AlternativeEmpty[F], afx: Arbitrary[F[X]], ef: Equal[F[X]]) =
forAll(f.alternativeEmptyLaw.leftOrElseIdentity[X] _)

def rightAlternativeIdentity[F[_], X](implicit f: AlternativeEmpty[F], afx: Arbitrary[F[X]], ef: Equal[F[X]]) =
forAll(f.alternativeEmptyLaw.rightOrElseIdentity[X] _)

def laws[F[_]](implicit F: AlternativeEmpty[F], afx: Arbitrary[F[Int]], af: Arbitrary[Int => Int], ef: Equal[F[Int]]) = new Properties("alternativeEmpty") {
include(alternative.laws[F])
property("left orElse identity") = leftAlternativeIdentity[F, Int]
property("right orElse identity") = rightAlternativeIdentity[F, Int]
}
}

object monadPlus {
def emptyMap[F[_], X](implicit f: MonadPlus[F], afx: Arbitrary[X => X], ef: Equal[F[X]]) =
forAll(f.monadPlusLaw.emptyMap[X] _)
Expand Down
8 changes: 6 additions & 2 deletions tests/src/test/scala/scalaz/KleisliTest.scala
Expand Up @@ -24,11 +24,15 @@ class KleisliTest extends Spec {
M.equal(mb1, mb2)
}
}

"mapK" ! check {
(f: Int => Option[Int], a: Int) =>
Kleisli(f).mapK(_.toList.map(_.toString)).run(a) must be_===(f(a).toList.map(_.toString))
}

checkAll(monoid.laws[KleisliOptInt[Int]])
checkAll(monadPlus.laws[KleisliOptInt])
checkAll(category.laws[KleisliOpt])
checkAll(alternativeEmpty.laws[KleisliOptInt])

object instances {
def semigroup[F[_], A, B](implicit FB: Semigroup[F[B]]) = Semigroup[Kleisli[F, A, B]]
Expand Down Expand Up @@ -61,4 +65,4 @@ class KleisliTest extends Spec {
def plus[F[_] : PlusEmpty, A] = Plus[({type f[a] = Kleisli[F, A, a]})#f]
def empty[F[_] : MonadPlus, A] = PlusEmpty[({type f[a] = Kleisli[F, A, a]})#f]
}
}
}
1 change: 0 additions & 1 deletion tests/src/test/scala/scalaz/OptionTTest.scala
Expand Up @@ -12,7 +12,6 @@ class OptionTTest extends Spec {
checkAll(equal.laws[OptionTList[Int]])
checkAll(monad.laws[OptionTList])
checkAll(traverse.laws[OptionTList])
checkAll(alternativeEmpty.laws[OptionTOption])

object instances {
def functor[F[_] : Functor] = Functor[({type λ[α] = OptionT[F, α]})#λ]
Expand Down
6 changes: 0 additions & 6 deletions tests/src/test/scala/scalaz/std/ListTest.scala
Expand Up @@ -9,7 +9,6 @@ class ListTest extends Spec {
checkAll(monoid.laws[List[Int]])
checkAll(monadPlus.laws[List])
checkAll(traverse.laws[List])
checkAll(alternative.laws[List])

import std.list.listSyntax._
import syntax.monad._
Expand Down Expand Up @@ -61,9 +60,4 @@ class ListTest extends Spec {
val actual = takeWhileN("/abc/def/hij/klm".toList, 4)(_ != '/').mkString
actual must be_===("/abc/def/hij")
}

"alternative" in {
Alternative[List].orElse(List(), List(0)) must be_===(List(0))
Alternative[List].orElse(List(0), List(1)) must be_===(List(0, 1))
}
}
1 change: 0 additions & 1 deletion tests/src/test/scala/scalaz/std/OptionTest.scala
Expand Up @@ -15,7 +15,6 @@ class OptionTest extends Spec {
checkAll("Option", monoid.laws[Option[Int]])
checkAll("Option", monadPlus.laws[Option])
checkAll("Option", traverse.laws[Option])
checkAll("Option", alternativeEmpty.laws[Option])

checkAll("Option @@ First", monoid.laws[Option[Int] @@ First])
checkAll("Option @@ Last", monoid.laws[Option[Int] @@ Last])
Expand Down

1 comment on commit 42ee545

@purefn
Copy link
Contributor Author

@purefn purefn commented on 42ee545 Feb 8, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add instances for ApplicativePlus.

I also seem to be seeing a failure in the ListTTest. Seems that ListT.fromList[Option, Int](None).flatMap(_ => MonadPlus[({type l[a] = ListT[Option, a]})#l].empty) is coming up as ListT.fromList[Option, Int](None) which is not equal to empty - which is defined as M point Done. The empty definition for MonadPlus doesn't seem right to me. It seems like it should use MonadPlus[M].empty. I don't see how else the MonadPlus laws can be satisfied.

Please sign in to comment.