Haskell Style - Pattern Matching with case vs. function declarations

Hi All, I am new to Haskell. I just started reading "Real World Haskell" a few days ago, so I apologize for being such a noob. But, I am curious why I see a lot of code where people do pattern matching via multiple function declarations instead of using the case ... of ... construct? For example: [code] foldl' _ zero [] = zero foldl' step zero (x:xs) = let new = step zero x in new `seq` foldl' step new xs [/code] instead of this, which I prefer: [code] foldl' f acc xs = case xs of [] -> acc (x:xs) -> let new = f acc x in new `seq` foldl' f new xs [/code] -- View this message in context: http://www.nabble.com/Haskell-Style---Pattern-Matching-with-case-vs.-functio... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Wed, Mar 18, 2009 at 1:49 PM, Tom.Amundsen
Hi All,
I am new to Haskell. I just started reading "Real World Haskell" a few days ago, so I apologize for being such a noob.
But, I am curious why I see a lot of code where people do pattern matching via multiple function declarations instead of using the case ... of ... construct? For example:
[code] foldl' _ zero [] = zero foldl' step zero (x:xs) = let new = step zero x in new `seq` foldl' step new xs [/code]
instead of this, which I prefer:
[code] foldl' f acc xs = case xs of [] -> acc (x:xs) -> let new = f acc x in new `seq` foldl' f new xs [/code]
Personally, I prefer the former for several reasons: it has less syntax (no case...of...->...-> stuff), it's easier to manipulate textually, it's less indented, and it's somewhat mentally easier to follow, since case feels imperative and step-by-step. Might as well ask why people prefer guard syntax to nesting if-then-elses; sure, they may be converted into the same code under the hood and be equivalent in power, but one scales better (in terms of clarity). -- gwern

On Wed, Mar 18, 2009 at 12:49 PM, Tom.Amundsen
Hi All,
I am new to Haskell. I just started reading "Real World Haskell" a few days ago, so I apologize for being such a noob.
But, I am curious why I see a lot of code where people do pattern matching via multiple function declarations instead of using the case ... of ... construct? For example:
[code] foldl' _ zero [] = zero foldl' step zero (x:xs) = let new = step zero x in new `seq` foldl' step new xs [/code]
instead of this, which I prefer:
[code] foldl' f acc xs = case xs of [] -> acc (x:xs) -> let new = f acc x in new `seq` foldl' f new xs [/code]
This is just my opinion, but pure functions are often compared to mathematical functions because they're similar in the way that neither depend on outside elements, only the inputs. Consider a mathematical "piecewise function" (http://en.wikipedia.org/wiki/Piecewise_function). These are typically defined as: f(x) = (*definition 1*) if condition1 f(x) = (*definition 2*) if condition2 etc... (Normally written with a large curly brace, but the idea is still the same). To me the notation here matches up nicely with the way of separating cases by defining them as multiple functions in Haskell because the choice of notation itself emphasizes that the function can be split into multiple completely separate computations depending on the format of the input.

On Wed, Mar 18, 2009 at 11:49 AM, Tom.Amundsen
Hi All,
I am new to Haskell. I just started reading "Real World Haskell" a few days ago, so I apologize for being such a noob.
But, I am curious why I see a lot of code where people do pattern matching via multiple function declarations instead of using the case ... of ... construct? For example:
[code] foldl' _ zero [] = zero foldl' step zero (x:xs) = let new = step zero x in new `seq` foldl' step new xs [/code]
Well, in this particular case, note that you have two equations written. These equations are true of foldl', and in fact foldl' is the *least defined * function satisfying these equations (see http://en.wikibooks.org/wiki/Haskell/Denotational_semantics for the underlying theory of "definedness"). It a very pretty idea. However, this happy view of equations breaks down once you start using the "fall through" semantics, as in: foo (x:y:xs) = x + y foo xs = 0 In which the second equation does not always hold (foo [1,2,3] = 0 is false). Because of this, I am beginning to prefer not writing functions using "fall through", although occasionally it is too damned convenient to pass up. Luke
participants (4)
-
Gwern Branwen
-
Luke Palmer
-
Tom.Amundsen
-
Zachary Turner