0

I trying to understand imap functor and have the following code:

trait Codec[A] {

  def encode(value: A): String

  def decode(value: String): A

  def imap[B](dec: A => B, enc: B => A): Codec[B] = {
    val self = this
    new Codec[B] {
      override def encode(value: B): String =
        self.encode(enc(value))

      override def decode(value: String): B =
        dec(self.decode(value))
    }
  }

}

object Codec {

  implicit val stringCodec: Codec[String] =
    new Codec[String] {
      override def encode(value: String): String = value
      override def decode(value: String): String = value
    }

  implicit val intCodec: Codec[Int] =
    stringCodec.imap(_.toInt, _.toString)

  implicit val booleanCodec: Codec[Boolean] =
    stringCodec.imap(_.toBoolean, _.toString)

  implicit val doubleCodec: Codec[Double] =
    stringCodec.imap(_.toDouble, _.toString)

  def encode[A](value: A)(implicit c: Codec[A]): String =
    c.encode(value)

  def decode[A](value: String)(implicit c: Codec[A]): A =
    c.decode(value)

}

Converting for example from double to string it works:

  def main(args: Array[String]): Unit = {
   println(Codec.encode(34.343))
  }

but from String to double:

  def main(args: Array[String]): Unit = {
   println(Codec.decode("34.343"))
  } 

I've got the error message:

Error:(44, 24) ambiguous implicit values:
 both value stringCodec in object Codec of type => io.khinkali.Codec[String]
 and value intCodec in object Codec of type => io.khinkali.Codec[Int]
 match expected type io.khinkali.Codec[A]
   println(Codec.decode("34.343"))
Error:(44, 24) could not find implicit value for parameter c: io.khinkali.Codec[A]
   println(Codec.decode("34.343"))
Error:(44, 24) not enough arguments for method decode: (implicit c: io.khinkali.Codec[A])A.
Unspecified value parameter c.
   println(Codec.decode("34.343"))

What do I forget?

softshipper
  • 32,463
  • 51
  • 192
  • 400

2 Answers2

1

You forgot to specify type for decode operation:

Codec.decode[Double]("34.343")

You have two implicit codecs in the scope: Codec[Int] and Codec[Double]. How does compiler know which one you want to use?

Sergii Lagutin
  • 10,561
  • 1
  • 34
  • 43
1

You have multiple options (implicits) for the decode function. If you specify the type parameter, then the compiler will be able to choose the right one: Codec.decode[Double]("34.343").

mpetruska
  • 633
  • 3
  • 6