I've been thinking about language design lately, and reading over some of the new things in Haskell (always a nice source of inspiration). I'm struck by the many odd uses of the left
<- and right
-> arrow operators.
I guess the many different usages comes from prior art in math and other languages regarding arrow syntax, but is there some other reason not to try and make the usage more consistent or clear? Maybe I'm just not seeing the big picture?
The right arrow gets used as a type constructor for functions, the separator between argument and body of lambda expressions, separator for case statements, and it's used in pattern views, which have the form
(e -> p).
The left arrow gets used in
do notation as something similar to variable binding, in list comprehensions for the same (I'm assuming they are the same, as list comprehensions look like condensed
do blocks), and in pattern guards, which have the form
(p <- e).
Now the last examples for each arrow are just silly! I understand that guards and views serve different purposes, but they have almost identical form except that one is the mirror of the other! I've also always found it kind of odd that regular functions are defined with
= but lambdas with
->. Why not use the arrow for both? Or the equals for both?
It also gets pretty odd when you consider that for comparing some calculated value against a constant, there's nearly a half-dozen ways to do it:
test x = x == 4 f x = if test x then g x else h x f' 4 = g 4 f' x = h x f'' x@(test -> true) = g x f'' _ = h x f''' x | true <- test x = g x | otherwise = h x f'''' x = case (x) of 4 -> g x _ -> h x
Variety is the spice of source code though, right?