2017-01-08 9 views
0

下記のScalaコンパイラエラーを解決しようとしています。現在、私はScalaZ、型崩れやモノクルに探していますScalaのコピーメソッドとサブタイプの多型

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

:これはようなものになるだろう(サブタイピングなし)(擬似)-Haskellで

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

一見して、単眼が疑問に思っていないようですが、私の直感が間違っていれば間違っていることを証明してください。

ScalaZ +シェイプレスかもしれないprobably仕事、私は確信しています(それらを使用したことはありません)。

1)Scalaでこれを解決する最も簡単な方法は何ですか?

2)ScalaZ自体で十分でしょうか?またはシェイプレスで十分ですか?または、2つの必要性の組み合わせですか?それとも別の方法ですか?

+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

面白い、ヒント@ジャスパー-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はサブタイプのフィールドもコピーできる必要があります。 Monocleはそれを行うことができますか?例えば ​​'DDがCC [E]を拡張している場合、' val d:String'フィールドを持っていれば 'f'は' d'もコピーする必要がありますが、 'CC [E] 'のレンズを生成するときには、 「d」。だから私はこれがどのように機能するのだろうか? – jhegedus

+0

はい、 'レンズ[CC [E]、リスト[E]]'をお持ちの場合は、 'DD extends CC [E]'の値に使用できます。しかし、 'Lens'を生成するために' @ Lenses'を使うことはできません。なぜなら、それは大文字小文字クラスに対してのみ機能し、それらを拡張することはできないからです。 –