[ghc-steering-committee] Proposal #302: Multiway lambda: time to vote
Richard Eisenberg
lists at richarde.dev
Sat Jul 17 18:22:29 UTC 2021
> On Jul 17, 2021, at 7:21 AM, Simon Marlow <marlowsd at gmail.com> wrote:
>
> Hi Richard - I'm curious about the coding style that you would advocate that uses it often. Can you give an example?
>
Sure:
> not :: Bool -> Bool
> not = \cases
> False -> True
> True -> False
>
> filter :: (a -> Bool) -> [a] -> [a]
> filter = \cases
> _ [] -> []
> pred (x : xs) | pred x -> x : filter pred xs
> | otherwise -> filter pred xs
This style has a few advantages over the more typical one:
- The name is not repeated each time, which is otherwise a refactoring hazard.
- The indentation of each line does not depend on the name, which is otherwise a separate refactoring hazard.
- It is possible to define a helper function in a where clause that scopes over the whole function.
Alternative version of filter
> filter :: (a -> Bool) -> [a] -> [a]
> filter pred = \cases
> [] -> []
> (x : xs) | pred x -> x : filtered
> | otherwise -> filtered
> where filtered = filter pred xs
This alternative has further advantages:
- It is clear which parameters are matched against and which are not (assuming the matched parameters go last).
- A `where` clause can scope over the whole function, or an individual match, depending on its indentation level.
A style more at odds with history might be
> filter :: forall a. (a -> Bool) -> [a] -> [a] = \cases
> ...
which is even less repetitive.
Would I *require* any of this for all of Haskell? Never. But it's appealing to me in its concision and expressive power.
Richard
More information about the ghc-steering-committee
mailing list