2016-06-14 9 views
0

私はSeq[R]を持っています。私はTuple2[Seq[E], Seq[S]]に分割したいと思いますが、これをコーディングしていましたが、Bifunctorというカスタムをseqsのタプルに使うことができるという事実を考えました。 :Bifunctorsのパラメータ型エイリアス

import scalaz.Bifunctor 

type MyType[E, S] = (Seq[E], Seq[S]) 

case class MyVali[E, S](tp: (Seq[E], Seq[S]))(implicit bifunctor: Bifunctor[MyType]) { 
    def bimap[C, D](f: (E) => C, g: (S) => D): (Seq[C], Seq[D]) = 
    bifunctor.bimap(tp)(f, g) 

    def leftMap[C](f: (E) => C): (Seq[C], Seq[S]) = 
    bifunctor.leftMap(tp)(f) 

    def rightMap[D](g: (S) => D): (Seq[E], Seq[D]) = 
    bifunctor.rightMap(tp)(g) 

} 

val myValBifunctorInstance = new Bifunctor[MyType] { 
    override def bimap[A, B, C, D](fab: (Seq[A], Seq[B]))(f: (A) => C, g: (B) => D): (Seq[C], Seq[D]) = 
    (fab._1.map(f), fab._2.map(g)) 
} 

MyVali((Seq.empty[String], Seq.empty[Int]))(myValBifunctorInstance).bimap(a => a, b => b) 

これはうまく動作しますが、私にははっきりしない何らかの理由で、私は、すなわちtype MyType[E, S] = (Seq[E], Seq[S])、すべてのこのコンパイルを行うためにパラメータ化タイプのエイリアスを宣言しなければならなかったし、これはそうではない、この作品、なぜ私はほとんど理解していない:

def myValBimap[E, S] = new Bifunctor[Tuple2[Seq[E], Seq[S]]] { 
    override def bimap[A, B, C, D](fab: (A, B))(f: (A) => C, g: (B) => D): (C, D) = ??? 
} 

[エラー] ...(配列[E]、配列[S])は期待、何型パラメータを取らない:myValBimap [E、S] DEF 2

[エラー]新しいBifunctor [Tuple2 [配列番号[= E]、配列は[S]]] {

は、このようなタイプの別名が定義されている場合(多分、ネストされたラムダ式のように?)2型の懸濁液を作成するコンパイラはありますか?

答えて

1
def myValBimap[E, S] = new Bifunctor[Tuple2[Seq[E], Seq[S]]] { ... } 

上記BifunctorTuple2[...]はもうESために充填されている2つの型パラメータを持っていません。

EgがmyValBimap[Int, String]Bifunctor[(Seq[Int], Seq[String])]と明確にタイプ(Seq[Int], Seq[String])は、どの2つのタイプがありません作成しようパラメーター。

あなたは親切なプロジェクターのプラグインを使用して

  • Bifunctor[({ type λ[α, β] = (Seq[α], Seq[β])})#λ]または
  • Bifunctor[λ[(α, β) => (Seq[α], Seq[β])]]を書くことができます。

    implicit def myBimap[F[_]: Functor]: Bifunctor[λ[(α, β) => (F[α], F[β])]] = ??? 
    

    単純な例では用の型パラメータを使用して論理和/ \/ためFunctorです:あなたは追加のタイプが必要な場合は、多分何かのようにあなたは、型パラメータを持つ暗黙の機能を必要とする

左側:あなたの元の問題について

implicit def functorDisj[L]: Functor[L \/ ?] = ??? 
implicit def functorDisj[L]: Functor[({ type λ[α] = L \/ α })#λ] = ??? 

:それは可能かもしれませんあなたのRE \/ Sにマッピングし、使用するseparate

import scalaz._, Scalaz._ 

val integers = List.range(1,10) 
val stringOrInts: List[String \/ Int] = 
    integers.map(i => if (i % 2 == 0) i.right else i.toString.left) 

stringOrInts.separate 
// (List[String], List[Int]) = (List(1, 3, 5, 7, 9),List(2, 4, 6, 8)) 
関連する問題