Find an instance of a type class for Shapeless HList in the Scalaz State Monad

Let's say that I have a state monad with a state HList, and I define a combinator that takes the first nelements of this HList:

import scalaz._, Scalaz._
import shapeless._,  ops.hlist._, Nat._

def take[S <: HList](n: Nat)(implicit tk: Take[S, n.N]):
    IndexedState[S, tk.Out, Unit] = ???

for {
  _ <- init[Int :: String :: HNil]
  _ <- take(_1)
  x <- state("abc")
} yield x

The scala compiler gets stuck during type inference. This does not mean that the Stype parameter takeis equal Int :: String :: HNil. Therefore, the compiler cannot find the implicit value for the parameter tk.

[error] could not find implicit value for parameter tk: shapeless.ops.hlist.Take[S,shapeless.Nat._1.N]
[error]     _ <- take(_1)

I know that I can help the compiler just expose the state or commit S. But I do not want! This additional information seems redundant:

def take[S <: HList](hl: S, n: Nat)(implicit tk: Take[S, n.N]):
    IndexedState[S, tk.Out, Unit] = ???

for {
  hl <- init[Int :: String :: HNil]
  _  <- take(hl, _1)          // Redundant
  _  <- take[Int :: HNil](_1) // Redundant
  x  <- state("abc")
} yield x

scala S Nothing Int :: String :: HNil? , , ?

!

+4
1

:

for {
  _ <- init[Int :: String :: HNil] flatMap { _  => take(_1) }
  x <- state("abc")
} yield x

for -loop

init[Int :: String :: HNil] flatMap { _ =>
  take(_1) flatMap { _ =>
    state("abc") map { x =>
      x
    }
  }
}

scalac, , take(_1), , , flatMap .

0

All Articles