Skip to content
Snippets Groups Projects
Commit cc594398 authored by Alexander Gehrke's avatar Alexander Gehrke
Browse files

[07] update for 2022

parent 30cb42ce
No related branches found
No related tags found
No related merge requests found
......@@ -2,18 +2,22 @@ package monads
trait Monad[F[_]]:
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = ???
extension [A](fa: F[A])
def flatMap[B](f: A => F[B]): F[B]
def sequence[A](fas: List[F[A]]): F[List[A]] = ???
def map2[B, C](fb: F[B])(f: (A, B) => C): F[C] = ???
extension [A](fas: List[F[A]])
def sequence: F[List[A]] = ???
def compose[A, B, C](f: A => F[B])(g: B => F[C]): A => F[C] = ???
trait Functor[F[_]]:
def map[A, B](a: F[A])(f: A => B): F[B]
extension [A](fa: F[A])
def map[B](f: A => B): F[B]
object Functor:
def functorFromMonad[F[_]](M: Monad[F]): Functor[F] = new Functor[F] {
def map[A, B](a: F[A])(f: A => B): F[B] = ???
}
def functorFromMonad[F[_]](using m: Monad[F]): Functor[F] = new Functor[F]:
extension [A](fa: F[A])
def map[B](f: A => B): F[B] = ???
......@@ -2,7 +2,8 @@ package monads
final case class Id[A](value: A)
object Id:
// No tests. If it compiles, it's correct.
given Monad[Id] with
def pure[A](a: A): Id[A] = ???
def flatMap[A, B](fa: Id[A])(f: A => Id[B]): Id[B] = ???
// No tests. If it compiles, it's correct.
given Monad[Id] with
def pure[A](a: A): Id[A] = ???
extension [A](fa: Id[A])
def flatMap[B](f: A => Id[B]): Id[B] = ???
......@@ -5,11 +5,12 @@ import testutil.PendingIfUnimplemented
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
given Monad[Option] with
def pure[A](a: A): Option[A] = Some(a)
extension [A](fa: Option[A]) def flatMap[B](f: A => Option[B]): Option[B] = fa.flatMap(f)
class MonadFunctorSpec extends AnyFlatSpec with Matchers with AppendedClues with PendingIfUnimplemented:
"functorFromMonad" should "return a working functor" in {
Functor.functorFromMonad[Option](new Monad[Option] {
def pure[A](a: A): Option[A] = Some(a)
def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] =
fa.flatMap(f)
}).map[Int, String](Some(3))(_.toString) shouldBe Some("3")
Functor.functorFromMonad[Option].map(Some(3))(_.toString) shouldBe Some("3")
}
......@@ -7,26 +7,25 @@ import org.scalatest.matchers.should.Matchers
class MonadSpec extends AnyFlatSpec with Matchers with AppendedClues with PendingIfUnimplemented:
"map2" should "combine two monadic values" in {
tupleMonad.map2(Tuple1(1), Tuple1(2))((a, b) => a + b) shouldBe Tuple1(3)
Tuple1(1).map2(Tuple1(2))((a, b) => a + b) shouldBe Tuple1(3)
}
"sequence" should "correctly sequence all values" in {
tupleMonad.sequence(List(
List(
Tuple1(1),
Tuple1(2),
Tuple1(3)
)) shouldBe Tuple1(List(1,2,3))
).sequence shouldBe Tuple1(List(1,2,3))
}
"compose" should "correctly compose monad functions" in {
val f: Int => Tuple1[Double] = a => Tuple1(a/2.0)
val g: Double => Tuple1[String] = a => Tuple1(a.toString)
tupleMonad.compose(f)(g)(3) shouldBe Tuple1("1.5")
summon[Monad[Tuple1]].compose(f)(g)(3) shouldBe Tuple1("1.5")
}
val tupleMonad = new Monad[Tuple1] {
given Monad[Tuple1] with
def pure[A](a: A): Tuple1[A] = Tuple1(a)
def flatMap[A, B](fa: Tuple1[A])(f: A => Tuple1[B]): Tuple1[B] =
f(fa._1)
}
extension [A](fa: Tuple1[A])
def flatMap[B](f: A => Tuple1[B]): Tuple1[B] = f(fa._1)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment