I posted a link to the following on the HaskellTwo wiki page. Please comment. I would like to suggest that PatternGuards NOT be included in HaskellTwo. While I enjoyed Simon Peyton Jones' well-written note on pattern guards [http://research.microsoft.com/Users/simonpj/Haskell/guards.html] very much, it was written a long time ago. Today it is easy to recognize that the problem he identifies is just the need for a monad, and that his proposed solution is a new syntax for introducing monadic calculations. The new syntax is messier and less general than the existing "do". Furthermore, the new syntax confuses the semantics of existing constructs. Referring to Simon's principal example in his note, here is one way to write "clunky" without PatternGuards:
clunky env var1 var2 = fromMaybe (var1 + var2) $ do val1 <- lookup env var1 val2 <- lookup env var2 return (val1 + val2)
Simple, clear, and scalable. -YitzGale
On Mon, Mar 28, 2005 at 02:17:46PM +0200, Yitzchak Gale wrote:
I posted a link to the following on the HaskellTwo wiki page. Please comment.
I would like to suggest that PatternGuards NOT be included in HaskellTwo.
While I enjoyed Simon Peyton Jones' well-written note on pattern guards [http://research.microsoft.com/Users/simonpj/Haskell/guards.html] very much, it was written a long time ago. Today it is easy to recognize that the problem he identifies is just the need for a monad, and that his proposed solution is a new syntax for introducing monadic calculations. The new syntax is messier and less general than the existing "do".
??? There is no conflict between the pattern guard syntax and the do syntax. in fact they are all of the same family, the most general being 'do' notation, list comprehensions being 'do' notation limited to the list monad and pattern guards being the 'do' notation limited to the identity monad.
Furthermore, the new syntax confuses the semantics of existing constructs.
Referring to Simon's principal example in his note, here is one way to write "clunky" without PatternGuards:
clunky env var1 var2 = fromMaybe (var1 + var2) $ do val1 <- lookup env var1 val2 <- lookup env var2 return (val1 + val2)
Now generalize it to more than two cases, or one where the second case needs to pattern match too. The magic of pattern guards is not in a single guarding expression, but in a function with many different cases which use pattern guards. Heh. Pattern guards are perhaps the best thing since sliced bread in my opinion :). certainly if I were to vote for an extension I couldn't live without they would be in the top 3. Oddly enough, I was looking over the old Haskell discussions, and pattern guards were supposed to make it into Haskell 98 according to the decision. Any idea what happened? did someone just forget to write them up or was there further discussion elsewhere? Old mailing list archives seem to be hard to come by. http://www.cs.chalmers.se/~rjmh/Haskell/Messages/Decisions.cgi John -- John Meacham - ⑆repetae.net⑆john⑈
John Meacham <john@repetae.net> writes:
Oddly enough, I was looking over the old Haskell discussions, and pattern guards were supposed to make it into Haskell 98 according to the decision. Any idea what happened? did someone just forget to write them up or was there further discussion elsewhere? Old mailing list archives seem to be hard to come by.
http://www.cs.chalmers.se/~rjmh/Haskell/Messages/Decisions.cgi
The Haskell'98 committee discussion /started/ on that message board, but unfortunately it records neither the complete discussion, nor the real final decisions. For various personal reasons, the editorship of the standard passed from John Hughes to Simon Peyton Jones towards the end of 1997. I believe the remainder of the discussions and decisions were made in public on the Haskell mailing list. Simon kept a firm hand on the tiller, sticking closely to the mandate for Standard Haskell, namely to fix bugs, remove traps for the unwary, and lift restrictions. New extensions were explicitly excluded. To find list archives for the relevant period (Jan-Dec 1998), you will have to search at <http://mail-archive.com/haskell@haskell.org/>. There does not appear to be an easy way to get a date-sorted segment of the archive without clicking 'earlier' several hundred times. :-( Here is at least some of the discussion on pattern guards: http://www.mail-archive.com/haskell@haskell.org/msg02045.html Regards, Malcolm
Now generalize it to more than two cases, or one where the second case needs to pattern match too. The magic of pattern guards is not in a single guarding expression, but in a function with many different cases which use pattern guards.
MonadPlus is your friend, especially if (fail s) is mzero. I tend to use something like the following "design pattern" to "lift" pattern match failure/case handling into the expression world: import Data.Maybe import Control.Monad clunky' env vars = fromJust $ do (var1:var2:vars) <- return vars val1 <- lookup var1 env val2 <- lookup var2 env return (val1 + val2) `mplus` do [var1] <- return vars -- .. some stuff .. return 1 `mplus` do [] <- return vars -- .. more stuff .. return 2 -- *Main> let env=[(1,5),(2,7)] *Main> clunky' env [1,2] 12 *Main> clunky' env [0] 1 *Main> clunky' env [] 2 Very handy for syntax-oriented programming and if combined with non-deterministic state transformers, as in parsers, type systems and the like. cheers, claus
participants (4)
-
Claus Reinke -
John Meacham -
Malcolm Wallace -
Yitzchak Gale