Continuing on Functional Programming in Scala's exercises, I'm trying to implement:
def sequence[A](n: Int, ma: F[A]): F[List[A]]
Except for traverse, replicateOnce and replicateM, which I wrote, author is #pchiusano EDIT (spelled name incorrectly, sorry)
trait Monad[F[_]] extends Functor[F] {
def unit[A](a: => A): F[A]
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]
def map[A,B](ma: F[A])(f: A => B): F[B] =
flatMap(ma)(a => unit(f(a)))
def map2[A, B, C](ma: F[A], mb: F[B])(f: (A,B) => C): F[C] =
flatMap(ma)(a => map(mb)(b => f(a, b)))
// Exercise 3: implement sequence() and traverse
// official answer from #pchiusano
def sequence[A](lma: List[F[A]]): F[List[A]] =
lma.foldRight(unit(List[A]()))((ma, mla) => map2(ma, mla)(_ :: _))
def traverse[A, B](la: List[A])(f: A => F[B]): F[List[B]] =
la.foldRight(unit(List[B]()))((ma, mla) => map2(f(ma), mla)(_ :: _))
def replicateOnce[A](ma: F[A]): F[List[A]] = {
map(ma)(x => List(x))
}
For replicateM, I'm getting a compile-time error, error: overloaded method value fill with alternatives.
// Exercise 4: implement replicateM
def replicateM[A](n: Int, ma: F[A]): F[List[A]] = {
sequence(List.fill(n, ma))
}
}
Please point me in the right direction as I'm a bit stuck.
You're calling List.fill incorrectly, it's a partially applied function so you need to first apply n and then ma:
def replicateM[A](n: Int, ma: F[A]): F[List[A]] = {
sequence(List.fill(n)(ma)) //note that the comma is removed
}
Related
I was trying to apply typeclass pattern in scala and tried implementing Functor, Applicative and Monad typeclasses as follows
trait Functor[F[_]] {
def fmap[A, B] : (A => B) => F[A] => F[B]
}
object Functor {
def fmap[A, B, F[_]] (implicit ev: Functor[F]) = ev.fmap
}
trait Applicative[F[_]] {
def pure[A]: A => F[A]
def apply[A, B]: F[A => B] => F[A] => F[B]
}
object Applicative {
def pure[A, F[_]: Applicative]: A => F[A] = implicitly[Applicative[F]].pure
def apply[A, B, F[_]: Applicative]: F[A => B] => F[A] => F[B] = implicitly[Applicative[F]].apply
def liftA2[A, B, C, F[_]: Functor: Applicative]: (A => B => C) => F[A] => F[B] => F[C] =
f => fa => fb => implicitly[Applicative[F]].apply(implicitly[Functor[F]].fmap(f)(fa))(fb)
}
trait Monad[M[_]] {
def bind[A, B]: M[A] => (A => M[B]) => M[B]
def ret[A]: A => M[A]
}
object Monad {
def bind[A, B, M[_] :Monad]: M[A] => (A => M[B]) => M[B] = implicitly[Monad[M]].bind
def ret[A, M[_] :Monad]: A => M[A] = implicitly[Monad[M]].ret
}
sealed trait Maybe[A]
case class Some[A](value: A) extends Maybe[A]
case object None extends Maybe[Void] {
def apply[A]: Maybe[A] = None.asInstanceOf[Maybe[A]]
}
object Maybe {
def apply[A] (value: A): Maybe[A] = Some(value)
implicit object MaybeOps extends Functor[Maybe] with Applicative[Maybe] with Monad[Maybe] {
override def fmap[A, B]: (A => B) => Maybe[A] => Maybe[B] =
fn => ma => ma match {
case Some(a) => Maybe(fn(a))
case _ => None.apply
}
override def pure[A]: A => Maybe[A] = Some(_)
override def ret[A]: A => Maybe[A] = Some(_)
override def apply[A, B]: Maybe[A => B] => Maybe[A] => Maybe[B] = mab => ma => mab match {
case Some(f) => fmap(f)(ma)
case _ => None.apply
}
override def bind[A, B]: Maybe[A] => (A => Maybe[B]) => Maybe[B] = ma => f => ma match {
case Some(a) => f(a)
case _ => None.apply
}
}
}
And the consumer logic where I get to apply bind, fmap functions on Maybe datatype does not typecheck:
val a: Maybe[Int] = Maybe(10)
val p: Maybe[String] = bind.apply(Maybe(10))((i: Int) => Maybe(s"$i values"))
val q = fmap.apply(i => s"$i !!")(p)
println(p)
println(q)
The above code getting the error as
Error: (15, 29) type mismatch; found: String required: Nothing val q = fmap.apply(i => s"$i !!")(p)
I didn't want to extend the trait to make it work. Since the context-bounds specify the requirement of Monad typeclass to require an instance of Applicative in scope. Is there any clean way to support this in scala?
Editing the above code as per #Mateusz Kubuszok comments, worked fine for me.
trait Functor[F[_]] {
//def fmap[A, B] : (A => B) => F[A] => F[B]
def fmap[A, B](f: A => B, fa: F[A]): F[B]
}
object Functor {
//def fmap[A, B, F[_]] (implicit ev: Functor[F]) = ev.fmap
def fmap[A, B, F[_]](f: A => B, fa: F[A]) (implicit ev: Functor[F]) = ev.fmap(f, fa)
}
trait Applicative[F[_]] {
//def pure[A]: A => F[A]
def pure[A](a: A) : F[A]
//def apply[A, B]: F[A => B] => F[A] => F[B]
def appl[A, B](f: F[A=>B], fa: F[A]): F[B]
}
object Applicative {
//def pure[A, F[_]: Applicative]: A => F[A] = implicitly[Applicative[F]].pure
def pure[A, F[_]](a: A)(implicit ev: Applicative[F]) = ev.pure(a)
//def apply[A, B, F[_]: Applicative]: F[A => B] => F[A] => F[B] = implicitly[Applicative[F]].apply
def appl[A, B, F[_]] (f: F[A => B], fa: F[A])(implicit ev: Applicative[F]): F[B]=
ev.appl(f, fa)
def liftA2[A, B, C, F[_]: Functor: Applicative] (f: (A => B => C), fa: F[A], fb: F[B]): F[C] =
implicitly[Applicative[F]].appl(implicitly[Functor[F]].fmap(f, fa), fb)
}
trait Monad[M[_]] {
//def bind[A, B]: M[A] => (A => M[B]) => M[B]
def bind[A, B](ma: M[A], f: A => M[B]): M[B]
//def ret[A]: A => M[A]
def ret[A](a: A): M[A]
}
object Monad {
// def bind[A, B, M[_] :Monad]: M[A] => (A => M[B]) => M[B] = implicitly[Monad[M]].bind
def bind[A, B, M[_] :Monad](ma: M[A], f: (A => M[B])): M[B] = implicitly[Monad[M]].bind(ma, f)
//def ret[A, M[_] :Monad]: A => M[A] = implicitly[Monad[M]].ret
def ret[A, M[_] :Monad](a: A)(implicit ev: Monad[M]): M[A] = ev.ret(a)
}
sealed trait Maybe[A]
case class Some[A](value: A) extends Maybe[A]
case object None extends Maybe[Void] {
def apply[A]: Maybe[A] = None.asInstanceOf[Maybe[A]]
}
object Maybe {
def apply[A] (value: A): Maybe[A] = Some(value)
implicit object MaybeOps extends Functor[Maybe] with Applicative[Maybe] with Monad[Maybe] {
override def fmap[A, B](f: (A => B), ma: Maybe[A]): Maybe[B] =
ma match {
case Some(a) => Maybe(f(a))
case _ => None.apply
}
override def pure[A](a: A) : Maybe[A] = Some(a)
override def ret[A](a: A) : Maybe[A] = Some(a)
override def appl[A, B] (mab: Maybe[A => B], ma: Maybe[A]): Maybe[B] = mab match {
case Some(f) => fmap(f, ma)
case _ => None.apply
}
override def bind[A, B](ma: Maybe[A], f: (A => Maybe[B])) : Maybe[B] = ma match {
case Some(a) => f(a)
case _ => None.apply
}
}
}
import io.github.senthilganeshs.typeclass.Monad.bind
import io.github.senthilganeshs.typeclass.Functor.fmap
import io.github.senthilganeshs.types.Maybe
object Main {
def main(args: Array[String]): Unit = {
import io.github.senthilganeshs.types.Maybe._
val a: Maybe[Int] = Maybe(10)
val p: Maybe[String] = bind(Maybe(10), (i: Int) => Maybe(s"$i values"))
val q: Maybe[String] = fmap((i: String) => s"$i !!", p)
println(p)
println(q)
}
}
we are creating our own OptionT of cats for understanding, how monads are work and monads transformation flow. While creating our own custom monad getting some of the errors. First thing below is our code:
case class WhateverOpt[W[_], A] (value: W[Option[A]]) {
def map[B] (f: A => B) (implicit M: Monad[W]): WhateverOpt[W, B] =
WhateverOpt(M.map(value)(_.map(f)))
def flatMap[B] (f: A => WhateverOpt[W, B]) (implicit M: Monad[W]): WhateverOpt[W, B] =
WhateverOpt(M.flatMap(value)(optA => optA match {
case Some(v) => f(v).value
}))
}
implicit val optionTMonad = new Monad[Option] {
override def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa.map(f)
override def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] = fa.flatMap(f)
}
val optionResult = for {
user <- WhateverOpt(repository.getUserOption(1))
addres <- WhateverOpt(repository.getAddressOption(user))
} yield addres.city
Below are the points, where we stuck:
How to handle None case in WhateverOpt flatMap method?
When executing the code, getting runtime error:
Error:(26, 12) could not find implicit value for parameter M: usercases.mtransfomer.Monad[scala.concurrent.Future]
addres <- WhateverOpt(repository.getAddressOption(user))
We are not sure about the error because we are creating optionTMonad implicit and by default, all are in the same scope. How can we resolve these two issues?
Update
Full code is available on Github branch https://github.com/harmeetsingh0013/fp_scala/blob/master/src/main/scala/usercases/mtransfomer/Example5.scala
About how to deal with None:
case class WhateverOpt[W[_], A] (value: W[Option[A]]) {
def map[B] (f: A => B) (implicit M: Monad[W]): WhateverOpt[W, B] =
WhateverOpt(M.map(value)(_.map(f)))
def flatMap[B]
(f: A => WhateverOpt[W, B])
(implicit wMonad: Monad[W])
: WhateverOpt[W, B] = {
WhateverOpt(wMonad.flatMap(value) { (oa: Option[A]) =>
oa match {
case None => wMonad.pure(None)
case Some(a) => f(a).value
}
})
}
}
Imagine for a second that W is Future. Then the above code says:
wait until the wrapped value yields a result oa of type Option[A]
If oa turns out to be None, then there is nothing we can do, because we cannot obtain any instances of type A in order to call f. Therefore, immediately return None. The immediately return is the pure-method of the Future-monad, so for the general case we have to invoke wMonad.pure(None).
If oa yields Some(a), we can give this a to f, and then immediately unpack it to get to the value of type W[Option[B]].
Once we have the W[Option[B]] (whether empty or not), we can wrap it into WhateverOpt and return from the flatMap method.
I assume that you wanted to reimplement Monad[Option] just for fun (it's already in the library (the catsStdInstancesForOption thing is a CommutativeMonad), but here is how you could re-build it:
implicit val optionTMonad = new Monad[Option] {
override def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa.map(f)
def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] = fa.flatMap(f)
def pure[A](a: A): Option[A] = Some(a)
def tailRecM[A, B](a: A)(f: (A) => Option[Either[A, B]]): Option[B] = {
f(a) match {
case Some(Left(nextA)) => tailRecM(nextA)(f)
case Some(Right(res)) => Some(res)
case None => None
}
}
}
Notice that 1.0.1 requires to implement pure and tailRecM, and does not provide default implementations for that.
I don't want to say much about the necessary imports for future, but the latest version has cats.instances.future which provides a Monad instance. Check this again, because it seems as if you are using a different version of cats (your version didn't complain because of the missing tailRecM in your Option-monad).
How to handle None case in WhateverOpt flatMap method?
This answer is already explained by #Gabriele Petronella and #Andrey Tyukin with details.
When executing the code, getting runtime error: Error:(26, 12) could
not find implicit value for parameter M:
usercases.mtransfomer.Monad[scala.concurrent.Future] addres <-
WhateverOpt(repository.getAddressOption(user))
This error occurs, because In WhateverOpt constructor we know that our value is W[Option[A]], where Option is already defined and handle by the code, but repository.getUserOption(1) return Future[Option[User]] where Future is handled by generic parameter W and in that, case, we need to define, how to handle monads for Future. For resolving that issue, we need to implement new Monad[Future] rather than, new Monad[Option] as below:
case class WhateverOpt[W[_], A] (value: W[Option[A]]) {
def map[B] (f: A => B) (implicit M: Monad[W]): WhateverOpt[W, B] =
WhateverOpt(M.map(value)(_.map(f)))
def flatMap[B] (f: A => WhateverOpt[W, B]) (implicit M: Monad[W]): WhateverOpt[W, B] =
WhateverOpt(M.flatMap(value)(optA => optA match {
case Some(v) => f(v).value
case None => M.pure(None)
}))
}
implicit val futureMonad = new Monad[Future] {
override def pure[A](a: A): Future[A] = Future.successful(a)
override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f)
override def flatMap[A, B](fa: Future[A])(f: A => Future[B]): Future[B] = fa.flatMap(f)
}
val optionResult: WhateverOpt[Future, String] = for {
user <- WhateverOpt(repository.getUserOption(1))
addres <- WhateverOpt(repository.getAddressOption(user))
} yield addres.city
I am not sure about my disription, which I mention in answere, but current my assumptions are this and for me above code is working fine. For a complete example, please click on the GitHub repo, which is mention in the question.
How to handle None case in WhateverOpt flatMap method?
When you flatMap over None you return None. When you flatMap over WhateverOpt[W[_], B] you want to return the pure of it, which in your code would be M.pure(None).
When executing the code, getting runtime error: Error:(26, 12) could not find implicit value for parameter M: usercases.mtransfomer.Monad[scala.concurrent.Future]
addres <- WhateverOpt(repository.getAddressOption(user))
That's a compile-time error (not a runtime one) and it's due to the missing instance of Monad[Future]. In order to get an instance of Monad[Future] in scope with cats, you can do:
import cats.instances.future._
import scala.concurrent.ExecutionContext.Implicits.global
Also, you can avoid declaring your own Monad[Option] by importing it from cats with
import cats.instances.option._
I'm using Scalaz as I'm loving a lot of aspects from Haskell's type class setup in the standard libraries. But exactly this is my current problem. I have a generic data structure with two generic parameters:
case class Parser[T,A](f: T => (T,A))
In Haskell I would implement the Alternative typeclass like this:
newtype Parser t a = Parser { runParser :: t -> (t,a) }
instance Alternative (Parser t) where
...
But how can I do something equivalent in Scala? As far as I know I can't do something like
object Parser {
implicit def ins_Alternative[T] = new Alternative[Parser[T]] {
// ...
}
}
Has anybody an idea how to do this? Thx in advance!
Update:
I've found this:
implicit def eitherMonad[L]: Traverse[Either[L, ?]] with MonadError[Either[L, ?], L] with BindRec[Either[L, ?]] with Cozip[Either[L, ?]] =
new Traverse[Either[L, ?]] with MonadError[Either[L, ?], L] with BindRec[Either[L, ?]] with Cozip[Either[L, ?]] {
def bind[A, B](fa: Either[L, A])(f: A => Either[L, B]) = fa match {
case Left(a) => Left(a)
case Right(b) => f(b)
}
// ...
}
in the Scalaz sources (https://github.com/scalaz/scalaz/blob/series/7.3.x/core/src/main/scala/scalaz/std/Either.scala).
According to this I guess I have to write something like
object Parser {
implicit def ins_Alternative[T] = new Alternative[Parser[T, ?]] {
// ...
}
}
which doesn't compile as the type ? is unknown.
I've found a solution.
implicit def ins_Alternative[T] = new Alternative[({type x[a] = Parser[T, a]})#x] {
override def empty[A]: Parser[T, A] = ???
override def plus[A](a: Parser[T, A], b: => Parser[T, A]): Parser[T, A] = ???
override def point[A](a: => A): Parser[T, A] = ???
override def ap[A, B](fa: => Parser[T, A])(f: => Parser[T, (A) => B]): Parser[T, B] = ???
}
I'm trying to implement map and flatMap as an extension/enrichment for Option, without cheating and looking at how it was implemented in Scalaz.
So here's what I got so far before I got stuck:
package extensions.monad
trait Monad[M[_]] {
// >>= :: Monad m => m a -> (a -> m b) -> m b
def flatMap[A, B](input: A => M[B]): M[B]
}
trait Functor[F[_]] {
// fmap :: Functor f => (a -> b) -> f a -> f b
def map[A, B](input: A => B): F[B]
}
object MOption {
implicit class MonadicOption[A](left: Option[A]) extends Monad[Option[A]] with Functor[Option[A]] {
def flatMap[A, B](right: A => Option[B]): Option[B] = ???
def map[A, B](right: A => B): Option[B] = ???
}
}
All I really need is the basic functionality, so I can do something like this:
Some(3).flatMap(x => Some(4).map(y => x + y))
Any hints?
def flatMap[A, B](right: A => Option[B]): Option[B] = left match {
None => None
Some(x) => right(x)
}
or similarly to what the scala std library does
def flatMap[A, B](right: A => Option[B]): Option[B] =
if (left.isEmtpy) None else right(left.get)
I am trying to implement a function that would work on types that have a map and a flatMap method. I have already made it for Traversable, but this does not include Future and Option directly. So I have decided to go with my own interface, using a typeclass:
trait CanMap[A, M[_]] {
def map[B](l: M[A])(f: A => B): M[B]
def flatMap[B](l: M[A])(f: A => M[B]): M[B]
}
I already implemented this for Option:
implicit def canmapopt[A] = new CanMap[A, Option] {
def map[B](l: Option[A])(f: A => B): Option[B] = l.map(f)
def flatMap[B](l: Option[A])(f: A => Option[B]): Option[B] = l.flatMap(f)
}
and this one works very well. Now I wanted to implement it for any subtype of Traversable, I tried an implementation very close to the one for Option:
implicit def canmaptrav[A, B, T[B] <: Traversable[B]] = new CanMap[A, T] {
def map[B](l: T[A])(f: A => B): T[B] = l.map(f)
def flatMap[B](l: T[A])(f: A => T[B]): T[B] = l.flatMap(f)
}
but I get the error:
type mismatch; found : Traversable[B] required: T[B] Note: implicit method canmaptrav is not applicable here because it comes after the application point and it lacks an explicit result type
for the return type of l.map. I cannot understand why l.map(f) would return a Traversable and not the specific type T[B]. So I tried to explicitelly put the right type of CanBuildFrom in the context:
implicit def canmaptrav[A, B, T[B] <: Traversable[B]](implicit cbf: CanBuildFrom[T[A], B, T[B]]) = new CanMap[A, T] {
def map[B](l: T[A])(f: A => B): T[B] = l.map(f)
def flatMap[B](l: T[A])(f: A => T[B]): T[B] = l.flatMap(f)
}
The error persists.
Any idea where I went wrong? It might be obvious but I am getting confused with the generic type signatures I guess.
Update: Solution
First of all, as the answers pointed out, CanMap is mostly a Functor/Monad, so if you dare, you can use scalaz to implement this. However, if you are like me and want to try without it, here is the solution, based on the answer by Kipton Barros:
trait CanMap[A, B, M[_]] {
def map(l: M[A])(f: A => B): M[B]
def flatMap(l: M[A])(f: A => M[B]): M[B]
}
implicit def canmapopt[A, B] = new CanMap[A, B, Option] {
def map(l: Option[A])(f: A => B): Option[B] = l.map(f)
def flatMap(l: Option[A])(f: A => Option[B]): Option[B] = l.flatMap(f)
}
implicit def canmaptrav[A, B, M[+_]](implicit bf: CanBuildFrom[M[A], B, M[B]], ev: M[A] => TraversableLike[A, M[A]], eb: M[B] => TraversableLike[B, M[B]]) = new CanMap[A, B, M] {
def map(l: M[A])(f: (A) => B): M[B] = l.map(f)
def flatMap(l: M[A])(f: A => M[B]): M[B] = l.flatMap[B, M[B]] { (a: A) =>
f(a)
}
}
The trick is to use an implicit conversion M[A] => TraversableLike[A, M[A]] instead of trying to subtype Traversable.
The first problem is that there's a lot going on "under the hood" in the Traversable map method. It does a bit of work to return the most specific collection type, which is why you need CanBuildFrom. The second problem is that Option does not implement the Traversable interface, so its map method doesn't take a CanBuildFrom.
Here's the closest I could get,
import scala.collection.generic.CanBuildFrom
import collection.TraversableLike
trait CanMap[A, M[_]] {
def map[B](l: M[A])(f: A => B)(implicit bf: CanBuildFrom[M[A], B, M[B]]): M[B]
}
object Test {
// ugly hack to work around nonexistent CanBuildFrom for Option
implicit def optionBuilder[A, B]: CanBuildFrom[Option[A], B, Option[B]] = null
implicit def canmapopt[A] = new CanMap[A, Option] {
def map[B](l: Option[A])(f: A => B)(implicit bf: CanBuildFrom[Option[A], B, Option[B]]): Option[B] = l.map(f)
}
implicit def canmaptrav[A, M[_]](implicit ev: M[A] => TraversableLike[A, M[A]]) = new CanMap[A, M] {
def map[B](l: M[A])(f: (A) => B)(implicit bf: CanBuildFrom[M[A], B, M[B]]): M[B] = l.map(f)
}
// example usage
def mapper[A, B, M[_]](l: M[A])(f: A => B)(implicit cm: CanMap[A,M], bf: CanBuildFrom[M[A], B, M[B]]) = {
cm.map(l)(f)
}
mapper(List(1,2,3))(_ + 1) // List(2,3,4)
mapper(Some(2): Option[Int])(_ + 1) // Some(3)
// (cast to Option[Int] is needed to find the canmapopt implicit)
}
By the way, the implicit conversion to TraversableLike makes this also work with arrays,
mapper(Array(1,2,3))(_ + 1) // Array(2, 3, 4)
Firstly I tried your two failed attempts and didn't got much out of it. Then I decided to go simple and do my own CanMap implementation. I ended up with this:
def canmaptrav[A] = new CanMap[A, Traversable]{
def map[B](l: Traversable[A])(f: A => B): Traversable[B]= l.map(f)
def flatMap[B](l: Traversable[A])(f: A => Traversable[B]): Traversable[B] = l.flatMap(f)
}
Looking exactly the CanMap[_,Option]. Assuming the subtypes you are looking for is for use cases like this:
canmaptrav[Int].map(List(1,2,3,4))(_ + 1) //> res0: Traversable[Int] = List(2, 3, 4, 5)
canmaptrav[Int].map(Vector(1,2,3,4))(_ + 1) //> res1: Traversable[Int] = Vector(2, 3, 4, 5)
Now, if you want res1 and res0 types to be the concrete types (List, Vector) than the approach will have to indeed rely on the CanBuildFrom from.
BTW, you know that the CanMap is almost the Monad interface, right?
Scalaz already includes these typeclasses and they are called Monad and Functor. A short example:
// map
def foo[F[_] : Functor](xs: F[Int]) = xs.map(_ + 1)
scala> foo(List(1,2,3))
res2: List[Int] = List(2, 3, 4)
// flatMap
def flatten[M[_] : Monad](xs: M[M[Int]]) = xs.flatMap(identity)
scala> flatten(List(List(1,2,3)))
res3: List[Int] = List(1, 2, 3)
edit:
The functor instance for Future could look like this:
implicit object FutureFunctor extends Functor[Future] {
def map[A,B](fa: Future[A])(f: A => B) = fa.map(f)
}