Implicit for Function not being found - scala

I have this typeclass
import simulacrum._
#typeclass trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B) : F[B]
def lift[A, B](fa: F[A])(f: A => B) : F[A] => F[B] = fa => map(fa)(f)
def as[A, B](fa: F[A], b: => B) : F[B] = map(fa)(_ => b)
def void[A](fa: F[A]) : F[Unit] = as(fa, ())
}
and this is the implementation
object Functor {
implicit val listFunctor: Functor[List] = new Functor[List] {
def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}
implicit def functionFunctor[X]: Functor[X => ?] = new Functor[X => ?] {
def map[A, B](fa : X => A)(f : A => B) = fa andThen f
}
}
I can easily discover the List implicit implementation as
object Chapter1 extends App {
import Functor.ops._
List(1, 2, 3).as("foo").foreach(println)
}
The above works perfectly fine. I can also do
object Chapter1 extends App {
import Functor._
val func : Int => String = implicitly[Functor[Int => ?]].map(_ + 2)(_.toString)
println(func(5))
}
But when I try
object Chapter1 extends App {
import Functor.ops._
val x : Int => Int = _ + 2
val y : Int => String = x.map(_.toString)
}
It doesn't find my implicit implementation and says that the value map is not a member of Int => Int

Compiler can't see that Int => Int is Int => ? applied to Int.
Add
scalacOptions += "-Ypartial-unification"
to build.sbt.
It's necessary for normal work with higher-kinded types with Cats, Scalaz or manually.
By the way, there's no sense to import Functor._

Related

Scala is unable to type check when higher kinded types are used

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)
}
}

Implementing Higher kinded types in scala via case class

Let's say I want to implement a map for Seq.
trait Functor2[F[_]] {
def map1[A,B](fa : F[A])(func: A => B) : F[B]
}
case class SeqFunctor1[A](fa: Seq[A]) extends Functor2[Seq] {
override def map1[A, B](fa: Seq[A])(func: A => B) : Seq[B] = fa map func
}
I can call this via
val list = List(1,2,3,4)
val f1 : Int => Int = (i : Int) => i * 10
SeqFunctor1(list).map1(list)(f1).
I do not like the fact that I have to use list twice. So I try this
trait Functor3[F[_]] {
def map1[A,B](func: A => B) : F[B]
}
case class SeqFunctor2[A](fa: Seq[A]) extends Functor3[Seq] {
override def map1[A, B](func: A => B) : Seq[B] = fa map func
}
so that I can use it via this
SeqFunctor2(list).map1(f1)
I get this error
Error:(45, 59) type mismatch;
found : A(in method map1) => B
required: A(in class SeqFunctor2) => ?
override def map1[A, B](func: A => B) : Seq[B] = fa map func
I know you can implement it via an object, but it would be nice to know how to use this via case class (and also a better way of doing it than the one that works).
You are shadowing your A in the case class definition with the one of your map definition. You could do this:
trait Functor3[F[_], A] {
def map1[B](func: A => B) : F[B]
}
case class SeqFunctor2[A](fa: Seq[A]) extends Functor3[Seq, A] {
override def map1[B](func: A => B) : Seq[B] = fa map func
}
val list = List(1,2,3,4)
val f1 : Int => Int = (i : Int) => i * 10
SeqFunctor2(list).map1(f1)
But why do you want to have your Functor as a case class? you really only need one instance of it.

Idiomatic approach to "composing" monoids using cats?

I would like to "compose" two monoids using cats. If there exists a defined Monoid[(A, A) => Int], then I would like to be able to create a Monoid[Preference[A]] using the combine and empty methods of the Monoid[(A, A) => Int]. I am using the term "composing" loosely here because I am not sure that the transform I want to do is accurately called composition.
Here is my current attempt...
import cats._
import cats.implicits._
trait Preference[A] extends Order[A]
object Preference {
def from[A](f: (A, A) => Int): Preference[A] = {
new Preference[A] {
def compare(a1: A, a2: A): Int = {
f(a1, a2)
}
}
}
def monoid[A](implicit ev: Monoid[(A, A) => Int]): Monoid[Preference[A]] = {
new Monoid[Preference[A]] {
def combine(p1: Preference[A], p2: Preference[A]): Preference[A] = {
new Preference[A] {
def compare(a1: A, a2:A): Int = {
ev.combine(p1.compare, p2.compare)(a1, a2)
}
}
}
def empty: Preference[A] = {
from(ev.empty)
}
}
}
}
...this compiles but I would like to know if there is a more idiomatic solution available using cats.
Seems like it should be possible to somehow compose the Monoid[(A,A) => Int] with the from combinator that takes a f:(A, A) => Int and returns a Preference[A] to create a Monoid[Preference[A]] but I can not figure out how to do it.
I have seen this SO post which discusses composing monoids using a product combinator which is not what I want.
I'm not aware of anything built-in into cats directly.
It seems that you have an isomorphism between Preference[A] and (A, A) => Int, and you simply want to transfer the monoid-structure from (A, A) => Int to Preference[A]. This can be expressed generically for arbitrary types A and B:
def fromIsomorphicMonoid[A, B](
forward: A => B,
inverse: B => A
)(implicit aMon: Monoid[A]): Monoid[B] = new Monoid[B] {
def combine(b1: B, b2: B): B =
forward(aMon.combine(inverse(b1), inverse(b2)))
def empty: B = forward(aMon.empty)
}
With this helper method, your monoid in Preference becomes just:
def monoid[A](implicit ev: Monoid[(A, A) => Int]): Monoid[Preference[A]] =
fromIsomorphicMonoid(
from,
(p: Preference[A]) => (x:A, y:A) => p.compare(x, y)
)
Full compilable example (without any dependencies):
trait Monoid[X] {
def empty: X
def combine(x: X, y: X): X
}
trait Order[A] {
def compare(a1: A, a2: A): Int
}
def fromIsomorphicMonoid[A, B](
forward: A => B,
inverse: B => A
)(implicit aMon: Monoid[A]): Monoid[B] = new Monoid[B] {
def combine(b1: B, b2: B): B =
forward(aMon.combine(inverse(b1), inverse(b2)))
def empty: B = forward(aMon.empty)
}
trait Preference[A] extends Order[A]
object Preference {
def from[A](f: (A, A) => Int): Preference[A] = {
new Preference[A] {
def compare(a1: A, a2: A): Int = {
f(a1, a2)
}
}
}
def monoid[A](implicit ev: Monoid[(A, A) => Int])
: Monoid[Preference[A]] = fromIsomorphicMonoid(
from,
(p: Preference[A]) => (x:A, y:A) => p.compare(x, y)
)
}

Scalacheck issue with higher kinds : diverging implicit expansion for type Arbitrary

I've defined a monad type class and I'm trying to verify its law with scalacheck.
I have the following error :
diverging implicit expansion for type org.scalacheck.Arbitrary[(A, Box[B])]
My scalacheck code is the following :
class OptionMonadSpec extends MonadSpec[String, String, String, Option](Monad.optionMonad)
abstract class MonadSpec[A, B, C, Box[_] : ClassTag](monad: Monad[Box])
(implicit boxArb: Arbitrary[Box[A]], aArb: Arbitrary[A], bArb: Arbitrary[B], cArb: Arbitrary[C])
extends Properties(s"Monad for ${classTag[Box[_]]}") {
property("left identity") = forAll { (f: (A => Box[B]), a: A) =>
val boxA: Box[A] = monad.pure(a)
monad.flatMap(boxA)(f) == f(a)
}
property("right identity") = forAll { box: Box[A] =>
monad.flatMap(box)(monad.pure) == monad
}
property("associativity") = forAll { (f: (A => Box[B]), g: (B => Box[C]), box: Box[A]) =>
val boxB: Box[B] = monad.flatMap(box)(f)
monad.flatMap(boxB)(g) == monad.flatMap(box) { a =>
val boxB: Box[B] = f(a)
monad.flatMap(boxB)(g)
}
}
}
Did I miss soemthing in the implicit Arbitrary types ?
Here is my monad :
trait Monad[Box[_]] extends Functor[Box] {
def pure[A](a: A): Box[A]
def flatMap[A, B](boxA: Box[A])(f: A => Box[B]): Box[B]
}
object Monad {
implicit val optionMonad = new Monad[Option] {
override def pure[A](x: A): Option[A] = Some(x)
override def flatMap[A, B](boxA: Option[A])(f: A => Option[B]) = boxA.flatMap(f)
override def map[A, B](boxA: Option[A])(f: A => B) = boxA.map(f)
}
}
Thanks
You have an implicit Arbitrary[Box[A]] in scope, but you don't have one for Arbitrary[Box[B]] (which Scalacheck needs to create one for A => Box[B]) or for Arbitrary[Box[C]] (which it'll ask for afterwards).
A more principled approach would be to create something like
trait Arbitrary1[F[_]] {
def liftArb[A](arb: Arbitrary[A]): Arbitrary[F[A]]
}
and provide Arbitrary1[Box] but it would require being more explicit when calling forAll.

Scala: How to use Functors for multi type parameter trait

I have and ADT which is basically a wrapper over Function1:
case class Abstract[M[_], A, B](f:M[A] => M[B]) {
def fn: M[A] => M[B] = { case x: M[A] => f(x) }
}
I want to map over these, so I defined a Functor like so:
trait AbstractAPI[E] {
type AbsO[T] = Abstract[List, E, T]
// type AbsO[T] = Abstract[List, _, T] => does not work (?)
implicit val abstractO: Functor[AbsO] = new Functor[AbsO] {
def map[A, B](fa: AbsO[A])(f: A => B): AbsO[B] = {
new Abstract(fa.fn andThen { x: List[A] => x.map{ y => f(y) } })
}
}
}
Now, to actually map over an Abstract, I'd need AbstractAPI[Int], like
case object IntAbstractAPI extends AbstractAPI[Int]
object A {
import IntAbstractAPI._
val f:List[Int] => List[String] = { case x: List[Int] => x.map{ _.toString.toLowerCase } }
val hey = (new Abstract(f)).map{ x => x.toInt }
}
or
object A extends AbstractAPI[Int] {
val f:List[Int] => List[String] = { case x: List[Int] => x.map{ _.toString.toLowerCase } }
// FINALLY!
val res = (new Abstract(f)).map{ x => x.toInt }.map{ _.toFloat + 10f }
// Abstract[List, Int, Float] = Abstract(<function1>)
}
However, in this pattern, I'd have to define case objects for every possible E. Here are my questions:
Is this the correct way to use Functors?
How can I automate the creation of the case objects for every possible E (or make the compiler infer it?)
Edit 1:
Further clarification: The above implementation works, but this one does not:
object A extends AbstractAPI {
val f:List[Int] => List[String] = { case x: List[Int] => x.map{ _.toString.toLowerCase } }
val res = (new Abstract(f)).map{ x => x.toInt }.map{ _.toFloat + 10f }
// Abstract[List, Int, Float] = Abstract(<function1>)
}
gives compilation error:
value map is not a member of Abstract[List,Int,String]
I assume this is because the compiler is not able to derive a functor for Abstract[List,Int,String]?
You can derive a functor for type parameters that you don't care about.
import cats.Functor
import cats.syntax.functor._
And I'll rename second type parameter on Abstract to X, it'll help
case class Abstract[M[_], X, A](f: M[X] => M[A]) // forget the fn bit for now
You can create typeclass instances not only with a val, but also with a def. It is allowed to have type parameters and also take other implicit (but only implicit) parameters.
type Abs1[X] = ({ type L[A] = Abstract[List, X, A] })
/*implicit*/ def abstract1[X]: Functor[Abs1[X]#L] = new Functor[Abs1[X]#L] {
override def map[A, B](fa: Abstract[List, X, A])(f: A => B): Abstract[List, X, B] =
Abstract(mx => fa.f(mx).map(f))
}
If map is all you need from a List, you can generalize further for any M[_] that has a Functor instance. Also placing it into a companion object of Abstract enables it to be found without additional imports / inheritance / etc.
object Abstract {
// Abstract.MX[M, X]#L can be replaced with Abstract[M, X, ?] if you use kind-projector
type MX[M[_], X] = ({ type L[A] = Abstract[M, X, A] })
implicit def genericFunctor[M[_]: Functor, X] = new Functor[MX[M, X]#L] {
override def map[A, B](fa: Abstract[M, X, A])(f: A => B): Abstract[M, X, B] =
Abstract(mx => fa.f(mx).map(f)) // the implementation is the same
}
}
And it works, if you import instances for whatever your M[_] is
assert {
import cats.instances.list._ // get Functor[List]
// map is automatically picked up from Functor[Abstract[List, Int, ?]]
Abstract(identity[List[Int]])
.map(Vector.range(0, _))
.map(_.mkString(""))
.f(List(1, 2, 3)) == List("0", "01", "012")
}
assert {
import cats.instances.option._
Abstract(identity[Option[Int]])
.map(_ min 42)
.map(i => Range(i, i + 3))
.f(Some(11)) == Some(Range(11, 14))
}
You can try the code there
Answering your second question, you could try this implicit AbstractAPI[T] factory:
implicit def abstractAPI[T]: AbstractAPI[T] = new AbstractAPI[T] {}
Any required implicit evidence for AbstractAPI[T] should work, e.g:
def f[T : AbstractAPI]: Unit = ()
f