arliss_obsidian/fp/Language/Expressions/case .. of.md

109 lines
2.2 KiB
Markdown
Raw Normal View History

2024-09-23 23:56:55 +00:00
Pattern matching
```haskell
case <expr> of
<arm>+
```
where `arm` is:
```haskell
<pattern> -> <expr>
```
`pattern` can be:
- [[Data Structures/data|data]] constructors
- [[Records|record]] literals, containing patterns
- integer & number literals
- string literals
- array literals, containing patterns
- wildcard `_`
### Guard Clauses
Case arms can have [[Functions/Defining/Guard Clause|guard clauses]] like [[Functions|function]] definitions:
```haskell
case _ of
"" -> Nothing
s | String.Util.startsWith "/" -> Just s
| otherwise -> Nothing
```
### Examples
Match on `Int` when zero
```haskell
nonzeroInt :: Int -> Maybe Int
nonzeroInt n =
case n of
0 -> Nothing
n' -> Just n'
```
Match on [[Arity|nullary]] [[Data Structures/data|data]] constructors:
```haskell
data Letter = A | B | C
letterToString :: Letter -> String
letterToString l =
case l of
A -> "a"
B -> "b"
C -> "c"
```
Match on [[Arity|unary]] [[Data Structures/data|data]] constructors:
```haskell
isJust :: forall a. Maybe a -> Boolean
isJust m =
case m of
Just a -> true
Nothing -> false
```
Match on [[Arity|binary+]] [[Data Structures/data|data]] constructors:
```haskell
data ComplexDataType = Complex Int Int String String
complex :: ComplexDataType -> String
complex m =
case m of
Complex a b c d -> (show a) <> (show b) <> c <> d
```
Match on a record field that is `Maybe`, continuing if the field is `Just`
```haskell
unMaybeFirstName :: {firstName :: Maybe String} -> Maybe {firstName :: String}
unMaybeFirstName r =
case r of
{firstName: Just fn} -> Just {firstName: fn}
_ -> Nothing
```
Match on an array of `a` into [[Either|either]]:
- [[Maybe|zero or one]] `a`
- an [[Array]] of 2 or more `a`s
```haskell
zeroOneOrMore ::
forall a
. Array a
-> Either (Maybe a) (Array a)
zeroOneOrMore a =
case a of
[] -> Left Nothing
[a] -> Left (Just a)
_ -> Right a
```
Deserialize strings literals into a [[Data Structures/data|data structure]]
```haskell
data Animal = Dog | Cat | Giraffe
animalFromString :: String -> Maybe Animal
animalFromString s =
case s of
"dog" -> Just Dog
"cat" -> Just Cat
"giraffe" -> Just Giraffe
_ -> Nothing
```