2017-01-08 5 views
0

Я пытаюсь решить следующую ошибку компилятора Scala ниже.метод копирования и полиморфизм подтипа в Scala

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" 
} 

В (псевдо) -Haskell (без суб-типирования), это будет что-то вроде:

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

В настоящее время я ищу в ScalaZ, Shapeless и Монокль.

На первый взгляд Монокль, кажется, не может быть и речи (не уверен, хотя), пожалуйста, докажите, что я ошибаюсь, если моя интуиция ошибается.

ScalaZ + Shapeless may probably работа, я не уверен, как (никогда не использовал их).

1) Что было бы самым простым способом решить эту проблему в Scala?

2) Будет ли ScalaZ само по себе достаточно? Или просто бесформенность сама по себе? Или это сочетание двух необходимых? Или, может быть, каким-то другим способом?

+0

Ммм это, кажется, ответ http://www.cakesolutions.net/teamblogs/copying-sealed-trait-instances-a-journey-through -generic-programming-and-shapeless – jhegedus

+0

Это также связано: http://stackoverflow.com/a/41000237/1374461 –

+0

Интересно, спасибо за подсказку @ Jasper-M – jhegedus

ответ

1

Вы можете сделать следующее с 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) 
} 
+0

Спасибо! Очень интересно ! Будет ли это работать, если 'cc' является подтипом' CC [E] '? Кажется, но я не уверен. В этом случае Monocle должен будет также скопировать поля подтипа. Может Монокль это сделать? Например, если 'DD extends CC [E]' имеет поле 'val d: String', то' f' также нужно будет скопировать 'd', но при генерации объектива для' CC [E] 'Monocle даже не знает о 'd'. Поэтому мне интересно, как это может работать? – jhegedus

+0

Да, если у вас есть объектив [CC [E], List [E]] ', вы можете использовать его для значения типа' DD extends CC [E] '. Однако вы не можете использовать '@ Lenses' для создания такого« объектива », потому что он работает только для классов case, и вы не можете их расширять. –

Смежные вопросы