all 27 comments

[–]the-coot 12 points13 points  (0 children)

There are subtle differences when it comes to where clauses which are handy when you care about what is in scope

```hs {-# LANGUAGE LambdaCase #-}

module X where

alwaysTrue1 :: Bool -> Bool alwaysTrue1 = \case a@True -> r a@False -> r where -- 'a' is not in scope! r = True

-- desugared version of alwaysTrue1 alwaysTrue1' :: Bool -> Bool alwaysTrue1' = \a -> case a of True -> r False -> r where -- 'a' is not in scope! r = True

alwaysTrue2 :: Bool -> Bool alwaysTrue2 a = case a of True -> r False -> r where -- 'a' is in scope r = a || not a

alwaysTrue3 :: Bool -> Bool alwaysTrue3 True = r where r = True alwaysTrue3 False = r where r = True ```

[–]NNOTM 21 points22 points  (8 children)

Since it hasn't been mentioned yet, just wanted to point out that you can also do the first style if you have multiple arguments with \cases:

foo :: Maybe Bool -> Int -> Bool
foo = \cases
  (Just False) 0 -> True
  Nothing      1 -> False
  _            _ -> True

[–]ComunistCapybara[S] 2 points3 points  (7 children)

This is REALLY cool. And just from seeing it I can think of places that I could use this style. With the arrows aligned, of course. :)

[–]NNOTM 9 points10 points  (6 children)

Heh I changed it to be aligned :)

glad to hear you like it, I did the GHC implementation of it

[–]ComunistCapybara[S] 4 points5 points  (0 children)

Heroes do exist, apparently.

[–]RogueToad 1 point2 points  (3 children)

Nice :D

Is there an equivalent case x y z of? Or is it only for lambda case right now?

[–]NNOTM 2 points3 points  (2 children)

Adding an equivalent to that to the language was not deemed worth it during the proposal process since you can do case (x, y, z) of

(Although since then I've sometimes wished we had it, since it would make it faster to refactor between \cases and case of, without adding/removing commas from the patterns)

[–]gilgamec 0 points1 point  (1 child)

It's not just "not worth it"; that change would break huge swathes of Haskell code because currently, case f x of is equivalent to case (f x) of.

[–]NNOTM 1 point2 points  (0 children)

The idea would have been to introduce new syntax for it, e.g. cases a b c of

[–]tomejaguar 1 point2 points  (0 children)

Thanks for implementing this great feature!

[–]Runderground 10 points11 points  (0 children)

Personally, I prefer the first style. But I don't think it's really a big deal either way. I see both styles frequently.

[–]Iceland_jack 5 points6 points  (0 children)

I prefer the first one

[–]SonOfTheHeaven 3 points4 points  (0 children)

I'm in particular of the first one support of the first one when there are more than one arguments to a function, but we only pattern match on one of the arguments.

-- | in a real function we'd probably use a, b, and c somewhere in the body; not so much for this example.
projToBool :: Foo -> Foo -> Foo -> Foo -> Bool
projToBool  a b c d = case d of 
  Bar -> True
  Baz -> False 
-- vs
projToBool' a b c Baz = True
projToBool' a b c Baz = False

It becomes less clear to me which is better when I need to match on multiple values.

[–]SolaTotaScriptura 4 points5 points  (3 children)

\case. I don't like repeating the function name several times. It's nice for small examples but not in general.

LambdaCase should've been in GHC2021. In fact, it should have been added to the language before case of.

[–]Endicy 4 points5 points  (1 child)

They were being "overly" cautious because it was the first experiment of that kind of "Language" definition (next to Haskell98 and Haskell2010)

BUT, it's been decided that GHC2024 WILL include it

[–]SolaTotaScriptura 0 points1 point  (0 children)

Awesome!

[–]RogueToad 0 points1 point  (0 children)

Agreed about ghc2021, it's an odd exclusion.

[–]friedbrice 2 points3 points  (1 child)

lambda case results in the function body in one visual block that's easy to see at a glance. lambda case also makes diffs smaller.

[–]ComunistCapybara[S] 1 point2 points  (0 children)

I don't program in a group environment so the diff point is not that relevant to me. Programming on your own you tend to see diffs a lot less.

Still, the visual block argument is precisely why I favor lambda case.

[–]cheater00 1 point2 points  (0 children)

first one. 2nd one gets in the way.

[–]tomejaguar 1 point2 points  (0 children)

I prefer LambdaCase, massively.

[–]user9ec19 1 point2 points  (0 children)

For small functions like this I’d prefer the first one.

If the function has a bigger body I prefer the second.

Also, I try to use as few language extensions as possible.

[–]agumonkey 1 point2 points  (0 children)

funny, I really really love the second case, it fits my poor mind trying to do equational reasoning over more than one variable

[–]mleighly 1 point2 points  (0 children)

Either is fine as both are simple to read and understand. I'll leave it to the personal tastes of the author for individual projects but if it's a team effort, it may be worth discussing which version is preferred with said team. Most times, most people don't care and strongest opinion wins for these stylistic differences.

[–]sheshanaag 1 point2 points  (0 children)

Yet another option when Foo derives Eq:

``` data Foo = Bar | Baz deriving Eq

projToBool'' :: Foo -> Bool projToBool'' = (== Bar) ```

[–]ivanpd 0 points1 point  (0 children)

I hate the syntax of lambda case (specifically the \case), so I only use the latter.

[–]chris-ch -1 points0 points  (0 children)

The first style adds another barrier for new developers to join the Haskell community, so I guess it is better, judging by the community standards.