Permalink
Browse files

๐Ÿ‘ถ

  • Loading branch information...
0 parents commit cf5a25aaaf380c0d0337ee9fc46e34b6e225ecc9 @dialelo dialelo committed Jun 6, 2016
Showing with 2,985 additions and 0 deletions.
  1. +32 โˆ’0 .gitignore
  2. +5 โˆ’0 .travis.yml
  3. +21 โˆ’0 build.sbt
  4. +1 โˆ’0 project/build.properties
  5. +1 โˆ’0 project/plugins.sbt
  6. +3 โˆ’0 src/main/resources/scala-exercises/library.47
  7. +57 โˆ’0 src/main/scala/catslib/Applicative.scala
  8. +153 โˆ’0 src/main/scala/catslib/Apply.scala
  9. +9 โˆ’0 src/main/scala/catslib/ApplyHelpers.scala
  10. +23 โˆ’0 src/main/scala/catslib/CatsLibrary.scala
  11. +184 โˆ’0 src/main/scala/catslib/Foldable.scala
  12. +141 โˆ’0 src/main/scala/catslib/FunctorSection.scala
  13. +85 โˆ’0 src/main/scala/catslib/IdentitySection.scala
  14. +135 โˆ’0 src/main/scala/catslib/Monad.scala
  15. +20 โˆ’0 src/main/scala/catslib/MonadHelpers.scala
  16. +88 โˆ’0 src/main/scala/catslib/Monoid.scala
  17. +100 โˆ’0 src/main/scala/catslib/Semigroup.scala
  18. +256 โˆ’0 src/main/scala/catslib/Traverse.scala
  19. +14 โˆ’0 src/main/scala/catslib/TraverseHelpers.scala
  20. +366 โˆ’0 src/main/scala/catslib/Validated.scala
  21. +74 โˆ’0 src/main/scala/catslib/ValidatedHelpers.scala
  22. +471 โˆ’0 src/main/scala/catslib/XorSection.scala
  23. +57 โˆ’0 src/test/scala/exercises/Test.scala
  24. +38 โˆ’0 src/test/scala/exercises/catslib/ApplicativeSpec.scala
  25. +85 โˆ’0 src/test/scala/exercises/catslib/ApplySpec.scala
  26. +138 โˆ’0 src/test/scala/exercises/catslib/FoldableSpec.scala
  27. +51 โˆ’0 src/test/scala/exercises/catslib/FunctorSpec.scala
  28. +38 โˆ’0 src/test/scala/exercises/catslib/IdentitySpec.scala
  29. +58 โˆ’0 src/test/scala/exercises/catslib/MonadSpec.scala
  30. +50 โˆ’0 src/test/scala/exercises/catslib/MonoidSpec.scala
  31. +40 โˆ’0 src/test/scala/exercises/catslib/SemigroupSpec.scala
  32. +52 โˆ’0 src/test/scala/exercises/catslib/TraverseSpec.scala
  33. +47 โˆ’0 src/test/scala/exercises/catslib/ValidatedSpec.scala
  34. +92 โˆ’0 src/test/scala/exercises/catslib/XorSpec.scala
@@ -0,0 +1,32 @@
+project/project
+project/target
+target
+.idea
+.tmp
+
+*.iml
+/out
+.idea_modules
+.classpath
+.project
+/RUNNING_PID
+.settings
+.sass-cache
+scalajvm/upload/*
+
+# temp files
+.~*
+*~
+*.orig
+
+# eclipse
+.scala_dependencies
+.buildpath
+.cache
+.target
+bin/
+.ensime
+.ensime_cache
+
+# OSX
+.DS_Store
@@ -0,0 +1,5 @@
+language: scala
+scala:
+ - 2.11.7
+jdk:
+ - oraclejdk8
@@ -0,0 +1,21 @@
+lazy val cats = (project in file("."))
+.enablePlugins(ExerciseCompilerPlugin)
+.settings(
+ organization := "org.scalaexercises",
+ name := "content-cats",
+ scalaVersion := "2.11.7",
+ version := "0.0.0-SNAPSHOT",
+ resolvers ++= Seq(
+ Resolver.sonatypeRepo("snapshots")
+ ),
+ libraryDependencies ++= Seq(
+ "org.typelevel" %% "cats-core" % "0.4.1",
+ "com.chuusai" %% "shapeless" % "2.2.5",
+ "org.scalatest" %% "scalatest" % "2.2.4",
+ "org.scalaexercises" %% "runtime" % "0.0.0-SNAPSHOT" changing(),
+ "org.scalaexercises" %% "definitions" % "0.0.0-SNAPSHOT" changing(),
+ "org.scalacheck" %% "scalacheck" % "1.12.5",
+ "com.github.alexarchambault" %% "scalacheck-shapeless_1.12" % "0.3.1",
+ compilerPlugin("org.spire-math" %% "kind-projector" % "0.7.1")
+ )
+)
@@ -0,0 +1 @@
+sbt.version=0.13.9
@@ -0,0 +1 @@
+addSbtPlugin("org.scalaexercises" % "sbt-exercise" % "0.0.0-SNAPSHOT", "0.13", "2.10")
@@ -0,0 +1,3 @@
+defaultLib.Library_cats$1$
+defaultLib.Library_shapeless$1$
+defaultLib.Library_stdlib$1$
@@ -0,0 +1,57 @@
+package catslib
+
+import org.scalatest._
+
+import cats._
+import cats.std.all._
+
+/** `Applicative` extends `Apply` by adding a single method, `pure`:
+ *
+ * {{{
+ * def pure[A](x: A): F[A]
+ * }}}
+ *
+ *
+ * @param name applicative
+ */
+object ApplicativeSection extends FlatSpec with Matchers with exercise.Section {
+
+ /** This method takes any value and returns the value in the context of
+ * the functor. For many familiar functors, how to do this is
+ * obvious. For `Option`, the `pure` operation wraps the value in
+ * `Some`. For `List`, the `pure` operation returns a single element
+ * `List`:
+ *
+ */
+ def pureMethod(res0: Option[Int], res1: List[Int]) = {
+ import cats._
+ import cats.std.all._
+
+ Applicative[Option].pure(1) should be(res0)
+ Applicative[List].pure(1) should be(res1)
+ }
+
+ /** Like `Functor` and `Apply`, `Applicative`
+ * functors also compose naturally with each other. When
+ * you compose one `Applicative` with another, the resulting `pure`
+ * operation will lift the passed value into one context, and the result
+ * into the other context:
+ */
+ def applicativeComposition(res0: List[Option[Int]]) = {
+ (Applicative[List] compose Applicative[Option]).pure(1) should be(res0)
+ }
+
+ /** = Applicative Functors & Monads =
+ *
+ * `Applicative` is a generalization of `Monad`, allowing expression
+ * of effectful computations in a pure functional way.
+ *
+ * `Applicative` is generally preferred to `Monad` when the structure of a
+ * computation is fixed a priori. That makes it possible to perform certain
+ * kinds of static analysis on applicative values.
+ */
+ def applicativesAndMonads(res0: Option[Int], res1: Option[Int]) = {
+ Monad[Option].pure(1) should be(res0)
+ Applicative[Option].pure(1) should be(res1)
+ }
+}
@@ -0,0 +1,153 @@
+package catslib
+
+import org.scalatest._
+import ApplyHelpers._
+
+import cats._
+import cats.std.all._
+import cats.syntax.apply._
+import cats.syntax.cartesian._
+
+/** `Apply` extends the `Functor` type class (which features the familiar `map`
+ * function) with a new function `ap`. The `ap` function is similar to `map`
+ * in that we are transforming a value in a context (a context being the `F` in `F[A]`;
+ * a context can be `Option`, `List` or `Future` for example).
+ * However, the difference between `ap` and `map` is that for `ap` the function that
+ * takes care of the transformation is of type `F[A => B]`, whereas for `map` it is `A => B`:
+ *
+ * Here are the implementations of `Apply` for the `Option` and `List` types:
+ * {{{
+ * import cats._
+ *
+ * implicit val optionApply: Apply[Option] = new Apply[Option] {
+ * def ap[A, B](f: Option[A => B])(fa: Option[A]): Option[B] =
+ * fa.flatMap (a => f.map (ff => ff(a)))
+ *
+ * def map[A,B](fa: Option[A])(f: A => B): Option[B] = fa map f
+ *
+ * def product[A, B](fa: Option[A], fb: Option[B]): Option[(A, B)] =
+ * fa.flatMap(a => fb.map(b => (a, b)))
+ * }
+ *
+ * implicit val listApply: Apply[List] = new Apply[List] {
+ * def ap[A, B](f: List[A => B])(fa: List[A]): List[B] =
+ * fa.flatMap (a => f.map (ff => ff(a)))
+ *
+ * def map[A,B](fa: List[A])(f: A => B): List[B] = fa map f
+ *
+ * def product[A, B](fa: List[A], fb: List[B]): List[(A, B)] =
+ * fa.zip(fb)
+ * }
+ * }}}
+ *
+ * @param name apply
+ */
+object ApplySection extends FlatSpec with Matchers with exercise.Section {
+ /** = map =
+ *
+ * Since `Apply` extends `Functor`, we can use the `map` method from `Functor`:
+ */
+ def applyExtendsFunctor(res0: Option[String], res1: Option[Int], res2: Option[Int]) = {
+ import cats.std.all._
+
+ val intToString: Int โ‡’ String = _.toString
+ val double: Int โ‡’ Int = _ * 2
+ val addTwo: Int โ‡’ Int = _ + 2
+
+ Apply[Option].map(Some(1))(intToString) should be(res0)
+ Apply[Option].map(Some(1))(double) should be(res1)
+ Apply[Option].map(None)(double) should be(res2)
+ }
+
+ /** = compose =
+ *
+ * And like functors, `Apply` instances also compose:
+ */
+ def applyComposes(res0: List[Option[Int]]) = {
+ val listOpt = Apply[List] compose Apply[Option]
+ val plusOne = (x: Int) โ‡’ x + 1
+ listOpt.ap(List(Some(plusOne)))(List(Some(1), None, Some(3))) should be(res0)
+ }
+
+ /** = ap =
+ *
+ * The `ap` method is a method that `Functor` does not have:
+ */
+ def applyAp(res0: Option[String], res1: Option[Int], res2: Option[Int], res3: Option[Int], res4: Option[Int]) = {
+ Apply[Option].ap(Some(intToString))(Some(1)) should be(res0)
+ Apply[Option].ap(Some(double))(Some(1)) should be(res1)
+ Apply[Option].ap(Some(double))(None) should be(res2)
+ Apply[Option].ap(None)(Some(1)) should be(res3)
+ Apply[Option].ap(None)(None) should be(res4)
+ }
+
+ /** = ap2, ap3, etc =
+ *
+ * `Apply` also offers variants of `ap`. The functions `apN` (for `N` between `2` and `22`)
+ * accept `N` arguments where `ap` accepts `1`.
+ *
+ * Note that if any of the arguments of this example is `None`, the
+ * final result is `None` as well. The effects of the context we are operating on
+ * are carried through the entire computation:
+ */
+ def applyApn(res0: Option[Int], res1: Option[Int], res2: Option[Int]) = {
+ val addArity2 = (a: Int, b: Int) โ‡’ a + b
+ Apply[Option].ap2(Some(addArity2))(Some(1), Some(2)) should be(res0)
+ Apply[Option].ap2(Some(addArity2))(Some(1), None) should be(res1)
+
+ val addArity3 = (a: Int, b: Int, c: Int) โ‡’ a + b + c
+ Apply[Option].ap3(Some(addArity3))(Some(1), Some(2), Some(3)) should be(res2)
+ }
+
+ /** = map2, map3, etc =
+ *
+ * Similarly, `mapN` functions are available:
+ *
+ */
+ def applyMapn(res0: Option[Int], res1: Option[Int]) = {
+ Apply[Option].map2(Some(1), Some(2))(addArity2) should be(res0)
+
+ Apply[Option].map3(Some(1), Some(2), Some(3))(addArity3) should be(res1)
+ }
+
+ /** = tuple2, tuple3, etc =
+ *
+ * Similarly, `tupleN` functions are available:
+ *
+ */
+ def applyTuplen(res0: Option[(Int, Int)], res1: Option[(Int, Int, Int)]) = {
+ Apply[Option].tuple2(Some(1), Some(2)) should be(res0)
+ Apply[Option].tuple3(Some(1), Some(2), Some(3)) should be(res1)
+ }
+
+ /** = apply builder syntax =
+ *
+ * The `|@|` operator offers an alternative syntax for the higher-arity `Apply`
+ * functions (`apN`, `mapN` and `tupleN`).
+ * In order to use it, first import `cats.syntax.all._` or `cats.syntax.apply._`.
+ *
+ * All instances created by `|@|` have `map`, `ap`, and `tupled` methods of the appropriate arity:
+ *
+ */
+ def applyBuilderSyntax(
+ res0: Option[Int],
+ res1: Option[Int],
+ res2: Option[Int],
+ res3: Option[Int],
+ res4: Option[(Int, Int)],
+ res5: Option[(Int, Int, Int)]
+ ) = {
+ val option2 = Option(1) |@| Option(2)
+ val option3 = option2 |@| Option.empty[Int]
+
+ option2 map addArity2 should be(res0)
+ option3 map addArity3 should be(res1)
+
+ option2 apWith Some(addArity2) should be(res2)
+ option3 apWith Some(addArity3) should be(res3)
+
+ option2.tupled should be(res4)
+ option3.tupled should be(res5)
+ }
+
+}
@@ -0,0 +1,9 @@
+package catslib
+
+object ApplyHelpers {
+ val intToString: Int โ‡’ String = _.toString
+ val double: Int โ‡’ Int = _ * 2
+ val addTwo: Int โ‡’ Int = _ + 2
+ val addArity2 = (a: Int, b: Int) โ‡’ a + b
+ val addArity3 = (a: Int, b: Int, c: Int) โ‡’ a + b + c
+}
@@ -0,0 +1,23 @@
+package catslib
+
+/** Cats is an experimental library intended to provide abstractions for functional programming in Scala.
+ *
+ * @param name cats
+ */
+object CatsLibrary extends exercise.Library {
+ override def color = Some("#4CAAF6")
+
+ override def sections = List(
+ MonoidSection,
+ SemigroupSection,
+ FunctorSection,
+ ApplySection,
+ ApplicativeSection,
+ MonadSection,
+ FoldableSection,
+ TraverseSection,
+ IdentitySection,
+ XorSection,
+ ValidatedSection
+ )
+}
Oops, something went wrong.

0 comments on commit cf5a25a

Please sign in to comment.