Case expressions, matching, and "constants"

I've just debugged a program that used a case expression, but where I was trying to match on constants rather than literals. Here's a contrived example:
module Main where one = 1 two = 2
test n = case n of one -> "one" two -> "two" _ -> "three"
main = putStrLn (test 2)
This initial version seems to me to be the "natural" way to write the case expression, but it doesn't work because the first alternative always succeeds. This is what I've turned it into to get it to work. It seems a bit clumsy; is there a better way to write this?
test n = case True of _ | n == one -> "one" | n == two -> "two" | otherwise -> "three"
***************************************************************** The information in this email and in any attachments is confidential and intended solely for the attention and use of the named addressee(s). This information may be subject to legal professional or other privilege or may otherwise be protected by work product immunity or other legal rules. It must not be disclosed to any person without our authority. If you are not the intended recipient, or a person responsible for delivering it to the intended recipient, you are not authorised to and must not disclose, copy, distribute, or retain this message or any part of it. *****************************************************************

At 12:03 PM +0100 7/17/03, Bayley, Alistair wrote:
I've just debugged a program that used a case expression, but where I was trying to match on constants rather than literals. Here's a contrived example:
module Main where one = 1 two = 2
test n = case n of one -> "one" two -> "two" _ -> "three"
main = putStrLn (test 2)
This initial version seems to me to be the "natural" way to write the case expression, but it doesn't work because the first alternative always succeeds.
The root of the problem is that a variable occurring in a pattern is always a new variable. A pattern variable provides a way to refer to the value to which the variable is bound when the pattern matches.
This is what I've turned it into to get it to work. It seems a bit clumsy; is there a better way to write this?
test n = case True of _ | n == one -> "one" | n == two -> "two" | otherwise -> "three"
As, Graham Klyne wrote at 2:52 PM +0100 7/17/03:
test n | n == one = "one" | n == two = "two" | otherwise = "three"
is a neater solution. Best, --Ham -- ------------------------------------------------------------------ Hamilton Richards, PhD Department of Computer Sciences Senior Lecturer The University of Texas at Austin 512-471-9525 1 University Station C0500 Taylor Hall 5.138 Austin, Texas 78712-1188 ham@cs.utexas.edu hrichrds@swbell.net ------------------------------------------------------------------

Hi Alistair, | I've just debugged a program that used a case expression, but | where I was trying to match on constants rather than literals. | Here's a contrived example: | | > module Main where | > one = 1 | > two = 2 | > | > test n = | > case n of | > one -> "one" | > two -> "two" | > _ -> "three" | > | > main = putStrLn (test 2) There's a 1992 tech report by Aitken and Reppy that provides a proposal for doing this kind of thing (and a bit more) in the context of SML: ftp://ftp.research.bell-labs.com/dist/smlnj/papers/92-tr-aitken.ps All the best, Mark

I've thought for a while that it would be nice to have a shorthand for `if` / `else if` chains. For example: if a < b then "less" else if a == b then "equal" else "greater" can be rendered with more structure as: case () of _ | a < b -> "less" | a == b -> "equal" | otherwise -> "greater" but would look even nicer as: case | a < b -> "less" | a == b -> "equal" | otherwise -> "greater" The shorthand just above requires a single addition to the Haskell grammar: exp10 -> `case` gdpat with trivial translation to: `case` () `of` { _ gdpat } -- Dean

On Thu, Jul 17, 2003 at 12:03:19PM +0100, Bayley, Alistair wrote:
This is what I've turned it into to get it to work. It seems a bit clumsy; is there a better way to write this?
test n = case True of _ | n == one -> "one" | n == two -> "two" | otherwise -> "three"
Or you might want to use something like this: (depending on how much your example resembles the actual code and the number of variables you want to match) module Main where one = 1 two = 2 test n = maybe d id (n `lookup` m) where m = [(one, "one") ,(two, "two") ] d = "three" -- Nobody can be exactly like me. Even I have trouble doing it.
participants (5)
-
Bayley, Alistair
-
Dean Herington
-
Hamilton Richards
-
Mark P Jones
-
Remi Turk