0

I am trying to solve the following Scala compiler error below.

case class CC[E](l:List[E])

trait D[E,L<:CC[E]]{
  def f(l:L):L = l.copy(l=List()) // does not compile: "found CC[E], required: L"
}

In (pseudo)-Haskell (without sub-typing) this would be something like :

 data CC = CC {l::[e]}
 'makeLens CC
 f l = l .~ _e []

Currently I am looking into ScalaZ, Shapeless and Monocle.

On a first glance Monocle seems to be out of question (not sure though), please prove me wrong, if my intuition is wrong.

ScalaZ + Shapeless might probably work, I am unsure how (never used them).

1) What would be the easiest way to solve this in Scala ?

2) Would ScalaZ in itself be enough ? Or Shapeless in itself is enough ? Or is the combination of the two neccessary ? Or maybe some other way ?

Community
  • 1
  • 1
jhegedus
  • 20,244
  • 16
  • 99
  • 167

1 Answers1

1

You could do the following with Monocle:

import monocle.macros.Lenses

@Lenses
case class CC[E](l:List[E])

object D {
  def f[E](cc: CC[E]): CC[E] = CC.l.set(List())(cc)
}
Julien Truffaut
  • 477
  • 4
  • 10
  • Thanks ! Very interesting ! Will this work if `cc` is a subtype of `CC[E]` ? It seems so but I am unsure. In that case Monocle would need to be able to copy also the fields of the subtype. Can Monocle do that ? For example if `DD extends CC[E]` has a field `val d: String` then `f` would need to copy `d` as well but when generating lens for `CC[E]` Monocle does not even know about `d`. So I wonder how can this work ? – jhegedus Jan 12 '17 at 20:34
  • yes, if you have a `Lens[CC[E], List[E]]` you can use it on a value of type `DD extends CC[E]`. However, you cannot use `@Lenses` to generate such a `Lens` because it only works for case classes and you can't extend them. – Julien Truffaut Jan 13 '17 at 20:50