Si tengo una instancia de Bifunctor[A,A]
bf, una función f : A => A
y un valor Boolean
p
:La invocación de una función en un "lado" de un bifuntor depende del valor de un booleano
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)
}
¿Cómo puedo poner esto de manera más concisa (y expresiva)? Básicamente, estoy tratando de invocar una función en un lado de un bifunctor (por ejemplo, un Tuple2
) dependiendo de algún predicado. Si el predicado es cierto, quiero asignar el LHS y el RHS si es falsa
val t2 = (1, 2)
def add4 = (_ : Int) + 4
calc(true, t2, add4) //should be (5,2)
calc(false, t2, add4) //should be (1,6)
Dado que yo quiero usar tuplas (a diferencia de la más general
Bifunctor
), que parecen ser capaces utilizar arrows de la siguiente manera:
def calc[A](p: Boolean, bf: (A, A), f: A => A): (A, A)
= (if (p) f.first[A] else f.second[A]) apply bf
El problema es que estoy escribiendo esto * en línea * (es decir, no quiero declarar un método adicional), así que no quiero tener que escribir 'bf' dos veces, porque es (en hecho) el resultado de una invocación a un método. La solución de flechas que encontré realmente funciona muy bien –
Debo decir que también quiero acceder solo a 'p' una vez también –
Para la solución de Haskell, ¿no necesita aplicar el resultado al bifunctor? ¿O es eso implícito? (No sé, haskell) –