Viktor Dukhovni ietf-dane at dukhovni.org
Fri Mar 26 21:03:30 UTC 2021

```On Fri, Mar 26, 2021 at 03:01:03PM -0500, Galaxy Being wrote:

> Now, what might be the purpose of this \ case?

It is just a short-hand:

\ case
pat1 -> e1
pat2 -> e2
...

is identical to:

\ x -> case x of
pat1 -> e1
pat2 -> e2
...

In other words, a concise function taking a single argument that is
immediately the verbatim subject of some pattern matches.

maybe fallback extract = \ case
Just av -> extract av
Nothing -> fallback

> In SML the code I gave simply looks like a trick to simulate a curry
> where the function takes a parameter, then morphs into a new function
> that takes the next parameter.

This is not a trick, it is elementary mathematical logic,
In set theory, we have an isomorphism:

A x B -> C      <---> A -> (B -> C)

this was eventually formalised in Churches Lambda Calculus.

λ(x,y). mumble  <--->  λx. (λy. mumble)
-- mumble = ..., some formula in x and y

> What would be the main use of this \ case ploy? I can't believe it was
> dreamt up just to fake currying.

I don't understand why you're using words like "fake" and "ploy".  This
is just a shorthand that avoids having to introduce a superfluous
intermediate variable that adds nothing to the clarity of the code.

> What's still strange to me is how the system knows to reach past the
> pred

That's just the same isomorphism, for fixed pred, (subst_c pred) is a
function of (a, MyList a).  But we can also view the same subst_c as a
function of two arguments (pred, (a, MyList a)).  The two viewpoints are
isomorphic.  The notation for anonymous functions allows us to avoid
having to name the restriction of `subst_c` to a given value of `pred`.

subst_c pred = \ (a, MyList a) -> mumble
<---> subst_c pred (a, MyList a) = mumble

> data MyList a = Empty | Cons a (MyList a) deriving (Eq, Ord, Show)
> subst_c :: (a -> Bool) -> (a, MyList a) -> MyList a
> subst_c pred = \ case
>                      (_, Empty)    -> Empty
>                      (n, Cons e t)
>                        | pred e    -> Cons n \$ subst_c pred (n, t)
>                        | otherwise -> Cons e \$ subst_c pred (n, t)
>
> and pattern match on the (a, MyList a) inside the function.

Well "closures" that capture a context, are immensely useful in writing
reusable software building blocks.  You can e.g. name "subst_c pred"
specialised for a particular predicate and use it repeatedly, or pass
it as a function to be used in some higher-order function.

> So again, how can it do this and why would I want to?

When working with higher-order functions, the function-valued arguments
passed to them are often partially-applied general-purpose "combinators".

Functional programming would be much more tediously verbose, if we
couldn't write function-valued expressions by partially applying

map (* 2) [1,2,3,4]

we'd have to always write:

map double [1,2,3,4]
where
double x = 2 * x

or similar.  Often the expression is at least as clear as any name
you might give it.

--
Viktor.
```