From 2c775ab486d19df91e92b2ecf77a7a723914f9e6 Mon Sep 17 00:00:00 2001 From: David Luposchainsky Date: Sat, 23 Jul 2016 09:58:06 +0200 Subject: [PATCH 1/2] Add LambdaCase proposal --- texts/.gitkeep | 2 - texts/0000-lambdacase.rst | 112 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 2 deletions(-) delete mode 100644 texts/.gitkeep create mode 100644 texts/0000-lambdacase.rst diff --git a/texts/.gitkeep b/texts/.gitkeep deleted file mode 100644 index ec86b32..0000000 --- a/texts/.gitkeep +++ /dev/null @@ -1,2 +0,0 @@ -(Dummy file because Git does not support committing empty folders. Safe to -remove once anything else is in the same directory.) \ No newline at end of file diff --git a/texts/0000-lambdacase.rst b/texts/0000-lambdacase.rst new file mode 100644 index 0000000..50ce130 --- /dev/null +++ b/texts/0000-lambdacase.rst @@ -0,0 +1,112 @@ +- Feature Name: LambdaCase +- Start Date: 2016-07-23 +- RFC PR: +- Haskell Report Issue: + + + +####### +Summary +####### + +For convenience, add the shorthand + +.. code-block:: haskell + + \case >>> \x -> case x of + Foo a -> … >>> Foo a -> … + … >>> … + +where ``x`` is a fresh variable. + +This is currently implemented via the ``LambdaCase`` GHC extension. + + + +########## +Motivation +########## + + +``LambdaCase`` is a syntactic convenience feature whose sole purpose is making +code a bit cleaner. + + +Example 1: Multiple pattern matches +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following example repeats the function name multiple times: + +.. code-block:: haskell + + myFunction (Foo (Just a)) = … + myFunction (Bar b) = … + myFunction (Qux (a,b)) = … + +Using lambda case, this could be refactored to + +.. code-block:: haskell + + myFunction = \case + Foo (Just a) -> … + Bar b -> … + Qux (a,b) -> … + +This lacks one level of parentheses, indents the patterns to make the top-level +definition stand out more, and avoids repeating the function name multiple +times. + + +Example 2: Monadic binding +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To pass a value through a monadic chain of binds, pattern matching on an +intermediate result requires creating a new variable whose only purpose is to be +scrutinized by a ``case`` again in the next step: + +.. code-block:: haskell + + main = foo >>= \x -> case x of Just bar -> … + Nothing -> … + +Lambda case would clean this up by getting rid of the intermediate variable, + +.. code-block:: haskell + + main = foo >>= \case Just bar -> … + Nothing -> … + + + +############### +Detailed design +############### + +The Summary_ already describes this to sufficient detail. + + + +######### +Drawbacks +######### + +There are no technical drawbacks. Since ``case`` is a reserved keyword in +Haskell, it cannot be used as a variable name. Therefore, in standard Haskell, +``\case`` is invalid. Thus, this proposal gives meaning to a previously +non-existing construct, resulting in no breakage. + + + +############ +Alternatives +############ + +No alternatives tackling the same issue are known (to me). + + + +#################### +Unresolved questions +#################### + +(none) \ No newline at end of file From e826ce30d2ae8a333bfe84981a7aafae821e6b7d Mon Sep 17 00:00:00 2001 From: David Luposchainsky Date: Thu, 22 Sep 2016 18:17:43 +0200 Subject: [PATCH 2/2] Mention inability to express multiple arguments --- texts/0000-lambdacase.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/texts/0000-lambdacase.rst b/texts/0000-lambdacase.rst index 50ce130..360fd9c 100644 --- a/texts/0000-lambdacase.rst +++ b/texts/0000-lambdacase.rst @@ -95,6 +95,10 @@ Haskell, it cannot be used as a variable name. Therefore, in standard Haskell, ``\case`` is invalid. Thus, this proposal gives meaning to a previously non-existing construct, resulting in no breakage. +Feature-wise, it is worth noting that lambda case does not support lambdas with +multiple arguments well. In this case, explicitly naming the `case` scrutinee, +as is current (standard Haskell) practice, explicitly. + ############