Pattern matching is a powerful feature in Haskell that allows you to destructure and extract information from data structures. It allows you to define functions and expressions based on different patterns that the input can match. Here's a brief explanation of how to use pattern matching in Haskell:
- Function Definitions: When defining functions, you can use pattern matching in the function definition. Each pattern corresponds to a specific input case. For example:
1 2 3 4 |
myFunction :: Int -> String myFunction 0 = "Zero" myFunction 1 = "One" myFunction x = "Other" |
In this example, if the input is 0, it will return "Zero". If the input is 1, it will return "One". And for any other input, it will return "Other".
- Function Arguments: Pattern matching can also be used to bind values to function arguments. For instance:
1 2 |
getFirst :: (a, b) -> a getFirst (x, y) = x |
Here, the function getFirst
takes a tuple as input and extracts the first element by pattern matching on (x, y)
. It assigns x
as the first element of the tuple.
- Lists and Recursion: Pattern matching is often used with lists and recursion. You can match specific elements or patterns within a list. For example:
1 2 3 |
mySum :: [Int] -> Int mySum [] = 0 mySum (x:xs) = x + mySum xs |
In this example, mySum
recursively sums up all the elements of a list. When the list is empty, it returns 0. Otherwise, it matches the input as (x:xs)
, where x
is the head and xs
is the tail of the list. The function then adds x
to the sum of the remaining elements.
These are just a few examples of how pattern matching can be used in Haskell. It is a powerful tool for working with complex data structures, allowing you to define behavior based on different patterns and cases.
How to match against empty lists in Haskell?
In Haskell, you can match against empty lists (also known as the empty case) using pattern matching or guards. Here are a few examples:
- Using pattern matching:
1 2 |
func [] = "Empty list" func (x:xs) = "Non-empty list" |
In this example, if the argument to func
is an empty list, it will match the pattern []
, and the function will return "Empty list". If the argument is a non-empty list, it will match the pattern (x:xs)
and return "Non-empty list".
- Using guards:
1 2 3 |
func lst | null lst = "Empty list" | otherwise = "Non-empty list" |
In this example, the function func
checks if the list lst
is empty using the null
function. If lst
is empty, it will evaluate the first guard (null lst
) and return "Empty list". Otherwise, it will evaluate the second guard (otherwise
) and return "Non-empty list".
These are just a few ways to match against empty lists in Haskell. Depending on your specific use case, you may choose a different approach.
How to match multiple patterns in Haskell?
To match multiple patterns in Haskell, you can use pattern guards, pattern synonyms, or the case expression.
- Pattern guards: You can use pattern guards by adding additional conditions to your function definition, using the | symbol. Each condition corresponds to a pattern, and when all conditions are met, the corresponding code block is executed. Here's an example:
1 2 3 4 5 |
myFunc :: Int -> String myFunc x | x < 0 = "Negative" | x == 0 = "Zero" | otherwise = "Positive" |
- Pattern synonyms: Pattern synonyms allow you to define additional patterns for existing data types. You can define multiple patterns and use them interchangeably with the original patterns. Here's an example:
1 2 3 4 5 6 7 8 9 |
pattern Empty = [] pattern Singleton a = [a] pattern Pair a b = (a, b) myFunc :: [Int] -> String myFunc Empty = "Empty list" myFunc (Singleton x) = "Singleton list" myFunc (Pair x y) = "Pair of elements" myFunc _ = "Other" |
- Case expressions: The case expression allows you to pattern match on an expression and execute different code blocks based on the matched pattern. Here's an example:
1 2 3 4 5 6 |
myFunc :: Int -> String myFunc x = case x of 0 -> "Zero" 1 -> "One" 2 -> "Two" _ -> "Other" |
In this example, the code block after each pattern, separated by ->
, will be executed based on the matched pattern.
These are some ways to match multiple patterns in Haskell. Choose the one that best suits your needs and style of programming.
What are constructors in pattern matching?
In pattern matching, constructors are symbols or data types that are used to define the structure of a data type. They are used to construct values of that data type.
For example, consider a simple data type called List
defined as:
1 2 |
data List a = Empty | Cons a (List a) |
In this definition, List
is the data type, and Empty
and Cons
are the constructors. Empty
represents an empty list, and Cons
represents a list with a value (a
) and a tail, which is also a List a
.
Constructors can be used in pattern matching to destructure and match against values of the defined data type. For example, to define a function to get the head of a List
, we can use pattern matching with the Cons
constructor:
1 2 |
head :: List a -> a head (Cons x _) = x |
Here, the pattern (Cons x _)
matches against a List
value constructed with the Cons
constructor. The first element of the Cons
constructor is bound to x
, which represents the head of the list. The underscore _
is used to match the tail of the list, but it is not used in the function body.