"binary" `bimap` - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

TheMatten

In some code, I'm folding sort of tree into Either a b, where b is the "better" result and a the "worse" one - to apply transformations on specific cases, I use bimap, like bimap worse better subpartResult- in cases where constructor carries 2 subtrees, I would like to choose better path if both subresults support it or worse option otherwise, for both, using transformation from better to worse option. Does this maybe fit into some sort of pattern, like single-subtree case does?

Chris Wendt

Hmm, what are the differences between "subpart", "subresult", and "subtree"? What "constructor" are you talking about? "choose better" sounds like Alternative.

TheMatten

subpartResult :: Either a b, where a is "worse" and b is "better" - I would like to generalize bimap onWorse onBetter subpartResult for two Eithers joined using binary operator

TheMatten

Having binary op for worse and better option

TheMatten

and ability to demote better into worse if one of them is worse

Chris Wendt

How does this look? Still not sure if I understand 100%

data Worse
data Better
type Result = Either Worse Better
demote :: Better -> Worse
mystery :: Result -> Result -> Result
mystery (Right better) (Right better) = better `combine` better
mystery l r = bimap id demote l `combine` bimap id demote r
Asad Saeeduddin

I don't quite understand the business with trees, but the applicative instance for Either will turn two Rights into a Right, and any other combination into a Left. Is this what you're referring to with:

I would like to choose better path if both subresults support it or worse option otherwise, for both, using transformation from better to worse option.

?

Asad Saeeduddin

i think i understand the problem a little bit better now. you've got some input of the form (e + a) × (e + b), and you need to mash it together into something else of the form e + c, and you're asking whether there's some general typeclass operation that Either happens to support which you can use to accomplish this.

i don't think there's anything readymade, the easiest way is probably to just write a concrete function:

op :: (a -> e) -> (b -> e) -> (e -> e -> e) -> (a -> b -> c) -> e + a -> e × b -> e + c
op = _
TheMatten

Yeah, that's basically what I did at the end :thumbs_up:

TheMatten

@Torsten Schmits my left side isn't used as Monoid- they're sorta equivalent, with right side being preferable whenever possible