How does HList.foldRight look for implicits when used in an implementation of a type class?

I'm new to using Shapeless, and I'm experimenting with Shapeless to automatically create a class class and bend over HLists. My goal is to do HListboth (a, b, c, d)using the scalaz.exe class implementation using types.Show

My first step was to experiment in a REPL with the following code

import shapeless._
import shapeless.ops.hlist._

object prettyPrint extends Poly2 {
  implicit def defaultCase[A] = at((a:A, z:String)=>s", ${a.toString}$z")
}

def print[H, T<:HList](f: H :: T)(implicit folder:RightFolder.Aux[H :: T, String, prettyPrint.type, String]) = {
  f.foldRight("")(prettyPrint)
}

val f = 1::'a::2::'b::HNil
val res = s"(${f.head}${print(f.tail)})" // Results res: String = (1, 'a, 2, 'b)

After that, I implemented the following method in my implementation LabelledTypeClassCompanion[...]. Unfortunately, this code does not compile because the compiler complains about the lack of implications, although I can’t say what is the difference between the code in REPL and the code below. My question is this is the problem in the code below and how to fix it?

def showFold[H, T<:HList](f: H::T)(implicit folder:RightFolder.Aux[ H::T, String, prettyPrint.type, String]) = {
  f.foldRight("")(prettyPrint)
}

override def product[H, T <: HList](name: String, ch: ScalazShow[H], ct: ScalazShow[T]): ScalazShow[H :: T] = {
  new ScalazShow[H :: T] {
    override def shows(ft: (H :: T)): String = {
     showFold(ft) // This does not compile
    }

  }
}

: (49, 18) : shapeless.ops.hlist.RightFolder.Aux [shapeless.:: [H, T], String, com.fpinscala.ninetynine.prettyPrint.type, String]        showFold (ft)//

package com.fpinscala.ninetynine

import shapeless._
import shapeless.ops.hlist.RightFolder

import scalaz.{Show => ScalazShow}

object prettyPrint extends Poly2 {
  implicit def defaultCase[A]:this.Case.Aux[A, String, String] = at[A, String]{
    (a,z) => s", $a$z"
  }
}


object ShowImpl extends LabelledTypeClassCompanion[ScalazShow] {

  implicit def symbolShow : ScalazShow[Symbol] = new ScalazShow[Symbol] {
    override def shows(f: Symbol): String = f.toString()
  }

  implicit def intShow : ScalazShow[Int] = new ScalazShow[Int] {
    override def shows(f: Int): String = f.toString
  }

  override val typeClass: LabelledTypeClass[ScalazShow] = new LabelledTypeClass[ScalazShow] {

    override def coproduct[L, R <: Coproduct](name: String, cl: => ScalazShow[L], cr: => ScalazShow[R]): ScalazShow[L :+: R] = new ScalazShow[L :+: R] {
      override def shows(lr: (L :+: R)): String = lr match {
        case Inl(l) => cl.shows(l)
        case Inr(r) => cr.shows(r)
      }
    }

    override def emptyCoproduct: ScalazShow[CNil] = new ScalazShow[CNil] {
      override def shows(f: CNil): String = ""
    }


    def showFold[H, T<:HList](f: H::T)(implicit folder:RightFolder.Aux[ H::T, String, prettyPrint.type, String]) = {
      f.foldRight("")(prettyPrint)
    }

    override def product[H, T <: HList](name: String, ch: ScalazShow[H], ct: ScalazShow[T]): ScalazShow[H :: T] = {
      new ScalazShow[H :: T] {
        override def shows(ft: (H :: T)): String = {
         showFold(ft) // This does not compile 
        }

      }
    }

    override def project[F, G](instance: => ScalazShow[G], to: (F) => G, from: (G) => F): ScalazShow[F] = new ScalazShow[F] {
      override def shows(f: F): String = instance.shows(to(f))
    }

    override def emptyProduct: ScalazShow[HNil] = new ScalazShow[HNil] {
      override def shows(f: HNil): String = ""
    }

  }
}
+6
1

( ). RightFolder, , LabelledTypeClass , ( , - ).

Update

, , TypeClass, , case , . ( TypeClass), :

scala> (123 :: "abc" :: HNil).shows
res2: String = (123, abc)

case , . , genericShow.

. , Show . - :

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> val x: Int = 123
x: Int = 123

scala> s"${ x.shows }${ x.shows }"
res0: String = 123123

x , .shows, Show . Scalaz Show[Int], , .

:

def toStringTwice[X](x: X): String = s"${ x.shows }${ x.shows }"

:

<console>:18: error: value shows is not a member of type parameter X
       def toStringTwice[X](x: X): String = s"${ x.shows }${ x.shows }"
                                                               ^

, , x Show, x. :

scala> def toStringTwice(x: String): String = s"${ x.shows }${ x.shows }"
toStringTwice: (x: String)String

scala> def toStringTwice(x: Int): String = s"${ x.shows }${ x.shows }"
toStringTwice: (x: Int)String

...

, . , Show, , , :

scala> def toStringTwice[X: Show](x: X): String = s"${ x.shows }${ x.shows }"
toStringTwice: [X](x: X)(implicit evidence$1: scalaz.Show[X])String

Int , Show:

scala> toStringTwice(123)
res2: String = 123123

, , :

def toStringFourTimes[X](x: X): String = s"${ toStringTwice(x) * 2 }"

:

scala> def toStringFourTimes[X: Show](x: X): String = s"${ toStringTwice(x) * 2 }"
toStringFourTimes: [X](x: X)(implicit evidence$1: scalaz.Show[X])String

- Show , . toStringTwice : Show , Show.

, Shapeless - .

, LabelledTypeClass, , TypeClass. , , .

, prettyPrint - Show A ( ), toString.

, , , :

import scalaz.Show, scalaz.Scalaz._
import shapeless._
import shapeless.ops.coproduct.Folder
import shapeless.ops.hlist.RightReducer

object prettyPrint2 extends Poly2 {
  implicit def defaultCase[A: Show]: Case.Aux[A, String, String] =
    at[A, String]((a, z) => s"$a, $z")
}

object prettyPrint extends Poly1 {
  implicit def defaultCase[A: Show]: Case.Aux[A, String] = at[A](_.shows)
}

implicit def hlistShow[L <: HList](implicit
  reducer: RightReducer.Aux[L, prettyPrint2.type, String]
): Show[L] = Show.shows(l => "(" + l.reduceRight(prettyPrint2) + ")")

implicit def coproductShow[C <: Coproduct](implicit
  folder: Folder.Aux[prettyPrint.type, C, String]
): Show[C] = Show.shows(_.fold(prettyPrint))

implicit def genericShow[A, R](implicit
  gen: Generic.Aux[A, R],
  reprShow: Show[R]
): Show[A] = reprShow.contramap(gen.to)

:

scala> Foo(123, "abc").shows
res0: String = (123, abc)

scala> (Foo(123, "abc"): Base).shows
res1: String = (123, abc)

, case .., - (. nofollow noreferrer → ). Scala ), , .

+6

Source: https://habr.com/ru/post/1016866/


All Articles