
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 existing functions. Instead of: 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.