0

With the following zipWith expression:

zipWith3 (\foos bars bazs -> case (foos, bars, bazs) of
    (foo, bar, Just baz)  -> Right "hell yeah"
    (foo, bar, Nothing) -> Left "tough luck"
) ["foo1", "foo2"] ["bar1", "bar2"] [Just "baz1", Just "baz2"]

Is it possible to use LambdaCase to simplify the case expression with something like (doesn't compile):

zipWith3 (\case
    (foo, bar, Just baz)  -> Right "hell yeah"
    (foo, bar, Nothing) -> Left "tough luck"
) ["foo1", "foo2"] ["bar1", "bar2"] [Just "baz1", Just "baz2"]

In the first (working) version, case receives a tuple, but in the (failing) LambdaCase version, it seems that case would receive the three arguments instead of a tuple. I don't know if this is possible to do something like that.

Jivan
  • 21,522
  • 15
  • 80
  • 131
  • I have sometimes wished for a lambda-multi-case feature. It's a shame there isn't one; I guess the biggest issue is working out what syntax to use to differentiate lambda-single-case from lambda-multi-case without stealing another keyword. Perhaps ```\case/``` or ```\case\``` for the multi version or something. – Daniel Wagner May 24 '21 at 12:44
  • 1
    Oh, and: you might like [`note`](https://hackage.haskell.org/package/errors-2.3.0/docs/Control-Error-Util.html#v:note). – Daniel Wagner May 24 '21 at 14:21

2 Answers2

4

You need to add curry3 (for example, from extra package):

zipWith3 (curry3 $ \case
    (foo, bar, Just baz)  -> Right "hell yeah"
    (foo, bar, Nothing) -> Left "tough luck"
) ["foo1", "foo2"] ["bar1", "bar2"] [Just "baz1", Just "baz2"]
SergeyKuz1001
  • 875
  • 1
  • 4
  • 6
1

Another option, since the pattern is only on the final argument, is to bind the first two with a normal lambda and the last with a lambdacase:

zipWith3 (\foo bar -> \case
    Just baz -> Right "hell yeah"
    Nothing -> Left "tough luck"
) [] [] []

I personally find this more visually pleasing, but have no particular technical reason to prefer this or the curry3 solution.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380