Many imperative __languages have Switch case__ syntax: we take a variable and execute blocks of code for specific values of that variable. We might also include a catch-all block of code in case the variable has some value for which we didn’t set up a case.

But Haskell takes this concept and generalizes it: __case constructs are expressions__, much like if expressions and let bindings. And we can do pattern matching in addition to evaluating expressions based on specific values of a variable

Speaking of pattern matching: we already saw this when we discussed function definitions. Well, that’s actually just syntactic sugar for case expressions. The two pieces of code below do the same thing and are interchangeable:

```
ghci 113> let {head' :: [a] -> a;
head' [ ] = error "No head for empty lists!";
head' (x: _) = x}
ghci 114> head' "whassup"
’w’
ghci 115> head' ""
*** Exception: No head for empty lists!
```

```
ghci 116> let {head" :: [a] -> a;
head" xs = case xs of {
[ ] -> error "No head for empty lists!";
(x: _) -> x} }
ghci 117> head00 "whassup"
’w’
ghci 118> head00 ""
*** Exception: No head for empty lists!
```

Thus, the syntax for case expressions is as follows

```
case expression of pattern -> result
pattern -> result
pattern -> result
....
```

The __expression is matched against the patterns__. The pattern matching action is what we expect: the first pattern that matches the expression is used. If we fall through the whole case expression and no suitable pattern is found, a runtime error occurs.

Note that, if we use both guards and case expressions in function definitions, __the guards cannot appear inside case expressions__, they have to take scope over them.

This goes well with the informal characterization of guards as presuppositions: they need to be specified before the function application is computed (i.e., the functional expression is evaluated / assigned a semantic value), hence they need to be specified before any specification of the function value.

In contrast, case expressions are just a way to specify actual function values, i.e., what should get computed assuming the guards / presuppositions are satisfied.

```
ghci 119> let {lessThanTwo :: (Integral a) => a -> String;
lessThanTwo x
| x < 2 = case x of {
0 -> "zero";
1 -> "one";
x -> "negative number"}
| otherwise = "two or more"}
```

```
ghci 120> lessThanTwo 0
"zero"
ghci 121> lessThanTwo 1
"one"
ghci 122> lessThanTwo (−5)
"negative number"
ghci 123> lessThanTwo 5
"two or more"
```

Whereas pattern matching on function parameters can only be done when defining functions, case expressions can be used pretty much anywhere. For instance, they are useful for pattern matching against something in the middle of an expression:

```
ghci 124> let {describeList :: [a] -> String;
describeList xs = "The list is " ++ case xs of {
[ ] -> "empty.";
[x] -> "a singleton list.";
xs -> "a longer list."} }
```

```
ghci 125> describeList [ ]
"The list is empty."
ghci 126> describeList [1]
"The list is a singleton list."
ghci 127> describeList [1 . . 5]
"The list is a longer list."
```

Alternatively, we could have used a where binding and a function definition like so:

```
ghci 128> let {describeList' :: [a] -> String;
describeList0 xs = "The list is " ++ what xs
where {
what [ ] = "empty.";
what [x] = "a singleton list.";
what xs = "a longer list."} }
```

```
ghci 129> describeList0
[ ]
"The list is empty."
```

```
ghci 130> describeList' [1]
"The list is a singleton list."
```

```
ghci 131> describeList' [1 . . 5]
"The list is a longer list."
```

But remember that a function definition with pattern matching is just syntactic sugar for a case expression, so using a where binding and a function definition like we did above is just a roundabout way of saying what we said more concisely with a case expression the first time around.

In this particular situation, going for a case expression directly improves readability because the case expression appears at the end of the main function definition. Using where just adds more words without improving readability. But there are cases in which where bindings are more readable, e.g., if the case expression would have to appear in the middle of the definition of the main function, or we would have to use multiple large case expressions etc.

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

You can attend first 3 classes for free, the total

The course time would be 8.00 PM(IST) for the first three classes

The course time would be 8.00 PM(IST) for the first three classes

If you are interested to learn then you can join the course by sending email to

| |||||