8

Bifunctor[A,A]bfのインスタンス、関数f : A => ABoolean値がある場合p

def calc[A, F[_,_]: Bifunctor](p: Boolean, bf: F[A, A], f: A => A): F[A, A] = {
  val BF = implicitly[Bifunctor[F]]
  BF.bimap(bf, (a : A) => if (p) f(a) else a, (a : A) => if (!p) f(a) else a)
}

どうすればこれをより簡潔に(そして表現力豊かに)置くことができますか?基本的に、私はいくつかの述語に依存するバイファンクター(例えば)の側で関数を呼び出そうとしています。Tuple2述語がtrueの場合、falseの場合はLHSとRHSをマップします

val t2 = (1, 2)
def add4 = (_ : Int) + 4
calc(true, t2, add4) //should be (5,2)
calc(false, t2, add4) //should be (1,6)


(より一般的なものではなく)タプルを使用したいので、次のように矢印Bifunctorを使用できるようです

def calc[A](p: Boolean, bf: (A, A), f: A => A): (A, A) 
  = (if (p) f.first[A] else f.second[A]) apply bf
4

3 に答える 3

4

それほど良いわけではありません:

def calc[A, F[_,_]:Bifunctor](p: Boolean, bf: F[A, A], f: A => A): F[A, A] =
   (if (p) (bf :-> (_: A => A)) else ((_:A => A) <-: bf))(f)

もう少しいい:

def cond[A:Zero](b: Boolean, a: A) = if (b) a else mzero

def calc[A, F[_,_]:Bifunctor](p: Boolean, bf: F[A, A], f: Endo[A]): F[A, A] =
  cond(p, f) <-: bf :-> cond(!p, f)

言語の羨望のためだけに、いくつかのHaskell:

calc p = if p then first else second
于 2010-11-11T18:00:03.303 に答える
0

(A,A)編集:代わりに戻るように修正A

何かが足りないかもしれませんが、これは一時変数の目的ではありませんか?通常のScalaタプルの場合:

Some(bf).map(x => if (p) x.copy(_1 = f(x._1)) else x.copy(_2 = f(x._2))).get

また

{ val (l,r) = bf; if (p) (f(l),r) else (l,f(r)) }
于 2010-11-11T19:07:17.660 に答える
0

Apocalispのソリューションのこのバリエーションは機能しますか?

def calc[A, F[_,_]:Bifunctor](p: Boolean, bf: F[A, A], f: A => A): F[A, A] =
   (if (p) ((_: F[A,A]) :-> f) else (f <-: (_: F[A,A])))(bf)

注:これはscalazでテストしていません。

于 2010-11-11T20:02:53.500 に答える