Aloha! :)
Could please somebody point me to a useful scala/cats tutorial? I’m struggling with making a class a functor for the last few days and I’m about to punch a hole in my display. All the documentation I’ve found up until now was not of help for me.
Maybe I should give Eta a try... =D
Here is the class I would like to turn into a functor. Besides 'show' doesn't behave the way I expected also.
package org.hudelundpfusch.utilites.decisions.data import cats.{Functor, Show} import cats.kernel.Eq import cats.syntax.functor._ import cats.syntax.show._ import scala.reflect.runtime.universe import scala.reflect.runtime.universe._ case class Fact[T <: Any] (name: String, value: T) (implicit private val paramTypeTagT: WeakTypeTag[T]) extends Equals { val paramType: universe.Type = paramTypeTagT.tpe val paramTypeClass: Option[Class[_ <: T]] = if (value != null) { Some(value.getClass) } else { None } def map[A, B](fa: Fact[A])(f: A => B): Fact[B] = Fact[B](fa.name, f(fa.value)) override def canEqual(other: Any): Boolean = other.isInstanceOf[Fact[_]] override def equals(other: Any): Boolean = other match { case that: Fact[_] => (that canEqual this) && name == that.name paramType == that.paramType && paramTypeClass == that.paramTypeClass && value == that.value case _ => false } override def hashCode(): Int = { val state = Seq(name, paramType, paramTypeClass, value) state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) } override def toString = s"Fact(name=${name}, paramType=$paramType, paramTypeClass=$paramTypeClass, value=$value)" } case object Fact extends Show[Fact[_]] { override def show(t: Fact[_]): String = t.toString } Thanks in advance
Have a nice day
Alex
Update:
package org.hudelundpfusch.utilites.decisions.data import cats.{Functor, Show} import cats.kernel.Eq import cats.syntax.functor._ import cats.syntax.show._ import scala.reflect.runtime.universe import scala.reflect.runtime.universe._ case class Fact[T <: Any] (name: String, value: T) (implicit private val paramTypeTagT: WeakTypeTag[T]) extends Functor[Fact] with Equals { val paramType: universe.Type = paramTypeTagT.tpe val paramTypeClass: Option[Class[_ <: T]] = if (value != null) { Some(value.getClass) } else { None } def map[A, B](fa: Fact[A])(f: A => B): Fact[B] = Fact[B](fa.name, f(fa.value)) override def canEqual(other: Any): Boolean = other.isInstanceOf[Fact[_]] override def equals(other: Any): Boolean = other match { case that: Fact[_] => (that canEqual this) && name == that.name paramType == that.paramType && paramTypeClass == that.paramTypeClass && value == that.value case _ => false } override def hashCode(): Int = { val state = Seq(name, paramType, paramTypeClass, value) state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) } override def toString = s"Fact(name=${name}, paramType=$paramType, paramTypeClass=$paramTypeClass, value=$value)" } Okay, I tried this now:
object Fact { implicit val factFunctor: Functor[Fact] = new Functor[Fact] { override def map[A, B](fa: Fact[A])(f: A => B): Fact[B] = Fact[B](fa.name, f(fa.value)) } implicit def factShow[T]: Show[Fact[T]] = new Show[Fact[T]] { override def show(t: Fact[T]): String = this.toString } } Unfortunately the call to the mapping function looks a bit cumbersome:
package org.hudelundpfusch.utilites.decisions.data object Fuddel { def main(args: Array[String]): Unit = { val fact1: Fact[Int] = Fact("Fact-1", 23) val fact2 = Fact.factFunctor.map(fact1){x: Int => x * 2} println(s"$fact2") } }
Functorexcept in the one import clause. Please provide a minimal reproducible example that demonstrates what the actual problem is.