Problem with assumed types when using Shapeless

I am having trouble getting the intended types of some extension methods that use Shapeless to match what (I think) they should be. I can assign the result of my val

explicitly typed expressions after passing them through identity

or through val

without an explicit type ( aaa

and bb

below respectively), but not directly ( c

below).

Tested using Scala 2.10.3, Shapeless 1.2.4, Scalaz 7.0.6.

import shapeless._, Tuples._
import scalaz._, Scalaz._
trait FnOps[=>:[_, _], A, B] {
  val F: Arrow[=>:]
  val f: A =>: B
  def &&&:[C](g: A =>: C): A =>: (C, B) =
    F.combine(g, f)
}
trait FnProdOps[=>:[_, _], A, B <: Product] {
  val F: Arrow[=>:]
  val f: A =>: B
  def &&&:[C, R <: HList](g: A =>: C)(implicit hlister: HListerAux[B, R], tupler: Tupler[C :: R]): A =>: tupler.Out =
    F.mapsnd(F.combine(g, f)) {
      case (c, b) => tupler(c +: hlister(b))
    }
}

trait LowPriorityImplicits0 {
  implicit def ToFnOps[=>:[_, _], A, B](fn: A =>: B)(implicit A: Arrow[=>:]): FnOps[=>:, A, B] =
    new FnOps[=>:, A, B] {
      val F = A
      val f = fn
    }
}
object Implicits extends LowPriorityImplicits0 {
  implicit def ToFnProdOps[=>:[_, _], A, B <: Product](fn: A =>: B)(implicit A: Arrow[=>:]): FnProdOps[=>:, A, B] =
    new FnProdOps[=>:, A, B] {
      val F = A
      val f = fn
    }
}

import Implicits._

// These work
val a: Int => Int = _ * 2
val aa: Int => (Int, Int) = a &&&: a
val aaa: Int => (Int, Int, Int) = identity(a &&&: a &&&: a)

// This works too
val b = a &&&: a &&&: a
val bb: Int => (Int, Int, Int) = b

// This doesn't
val c: Int => (Int, Int, Int) = a &&&: a &&&: a

      

Is there a way to make assignments similar to c

compile?

+3


source to share





All Articles