How to Use Pattern Matching In Haskell?

11 minutes read

Pattern matching is a powerful feature in Haskell that allows you to deconstruct data structures and extract values. It is used to define functions that behave differently based on the shape or contents of the input.


Here is a general syntax for pattern matching in Haskell:

1
2
3
4
5
functionName :: DataType -> ReturnType
functionName pattern1 = result1
functionName pattern2 = result2
...
functionName patternN = resultN


In the above code, functionName is the name of the function you're defining, DataType is the type of the input, and ReturnType is the type of the returned value. Each pattern corresponds to a different case, and the associated result is what will be returned when the input matches that particular pattern.


Pattern matching can be used with various datatypes, including lists, tuples, algebraic data types, and more. Here are some common pattern matching examples:

  1. Matching a single value:
1
2
3
isZero :: Int -> Bool
isZero 0 = True
isZero _ = False


In this example, if the input is 0, the pattern matches and True is returned. If the input is anything else, the _ acts as a catch-all pattern and False is returned.

  1. Matching a list:
1
2
3
isListEmpty :: [a] -> Bool
isListEmpty [] = True
isListEmpty _ = False


The first pattern matches an empty list [], and returns True. The second pattern, denoted by _, matches any non-empty list and returns False.

  1. Matching a tuple:
1
2
getFirstElement :: (a, b) -> a
getFirstElement (x, _) = x


Here, the first pattern matches any tuple (x, _) and returns the first element x. The _ is used to ignore the second element.


Pattern matching can also be nested, allowing you to match patterns within patterns. Additionally, you can use guards (conditionals) in combination with pattern matching for more complex logic.


Pattern matching is a fundamental concept in Haskell and is widely used to write concise and expressive code. It enables you to handle different cases of data effectively, making your functions more robust and versatile.

Best Haskell Books to Read in 2024

1
Get Programming with Haskell

Rating is 5 out of 5

Get Programming with Haskell

2
Haskell in Depth

Rating is 4.9 out of 5

Haskell in Depth

3
Programming in Haskell

Rating is 4.8 out of 5

Programming in Haskell

4
Parallel and Concurrent Programming in Haskell: Techniques for Multicore and Multithreaded Programming

Rating is 4.7 out of 5

Parallel and Concurrent Programming in Haskell: Techniques for Multicore and Multithreaded Programming

5
Programming in Haskell

Rating is 4.6 out of 5

Programming in Haskell

6
Haskell from the Very Beginning

Rating is 4.5 out of 5

Haskell from the Very Beginning

7
Developing Web Apps with Haskell and Yesod: Safety-Driven Web Development

Rating is 4.4 out of 5

Developing Web Apps with Haskell and Yesod: Safety-Driven Web Development

8
Real World Haskell: Code You Can Believe In

Rating is 4.3 out of 5

Real World Haskell: Code You Can Believe In

9
Haskell: The Craft of Functional Programming (International Computer Science Series)

Rating is 4.2 out of 5

Haskell: The Craft of Functional Programming (International Computer Science Series)

10
Effective Haskell: Solving Real-World Problems with Strongly Typed Functional Programming

Rating is 4.1 out of 5

Effective Haskell: Solving Real-World Problems with Strongly Typed Functional Programming


How to use pattern matching to handle different cases in algebraic data types in Haskell?

Pattern matching is a powerful mechanism in Haskell that allows you to handle different cases of algebraic data types. Here are the steps to use pattern matching effectively:

  1. Define your algebraic data type: Start by defining an algebraic data type using the data keyword. For example, consider a simple data type called Shape:
1
data Shape = Circle Double | Rectangle Double Double


This data type has two constructors: Circle and Rectangle, each taking different arguments.

  1. Write a function that operates on your data type: Create a function that pattern matches on different cases of your data type. For example, let's define an area function for our Shape type:
1
2
3
area :: Shape -> Double
area (Circle r) = pi * r * r
area (Rectangle b h) = b * h


In this case, the area function pattern matches on two cases: Circle r and Rectangle b h. It calculates the area accordingly based on the shape.

  1. Handle all possible cases: It's important to provide a pattern match for all possible cases of your data type. If you miss a case, Haskell will give you a compile-time warning, forcing you to handle all cases explicitly.


For example, if we add another constructor to our Shape data type called Triangle, the area function must be modified to handle this case as well:

1
2
3
4
5
6
data Shape = Circle Double | Rectangle Double Double | Triangle Double Double

area :: Shape -> Double
area (Circle r) = pi * r * r
area (Rectangle b h) = b * h
area (Triangle b h) = 0.5 * b * h


Here, we added a pattern match for Triangle which calculates its area.


By following these steps, you can effectively use pattern matching to handle different cases in algebraic data types in Haskell.


What are wildcards in pattern matching in Haskell and how to use them?

Wildcards in pattern matching in Haskell are placeholders that match any value. They are denoted by an underscore _ and can be used when you don't care about the value of a particular part of a pattern.


Here are a few examples of how wildcards can be used:

  1. Ignore a value: If you don't care about a particular value, you can use a wildcard to ignore it. For example, in the pattern matching below, the _ wildcard is used to ignore the second element of the list:
1
2
headAndTail :: [a] -> (a, [a])
headAndTail (x:_) = (x, _)


  1. Match against any value: Wildcards can also be used to match any value. For example, in the pattern matching below, the _ wildcard is used to match against any integer value:
1
2
3
isZero :: Int -> Bool
isZero 0 = True
isZero _ = False


  1. Extract some values and ignore others: Wildcards can be combined with specific patterns to extract certain values while ignoring others. For example, in the pattern matching below, the _ wildcard is used to ignore the second element of a tuple while extracting the first element:
1
2
fstElement :: (a, b) -> a
fstElement (x, _) = x


It's important to note that wildcards cannot be used multiple times in the same pattern, as it would be ambiguous and can lead to runtime errors. Wildcards can only be used to match a single value or to ignore a single value in a pattern.


What is pattern matching in list comprehensions in Haskell?

Pattern matching in list comprehensions in Haskell refers to the ability to destructure elements of a list or a tuple while iterating over it using list comprehensions. It allows you to bind variables to specific parts of the elements in the list or tuple and use those variables to manipulate or filter the elements in the list comprehension.


For example, consider the following list comprehension:

1
[(x, y) | (x, y) <- [(1, 2), (3, 4), (5, 6)], x + y >= 5]


In this example, the pattern (x, y) is used to destructure each pair (x, y) in the list [(1, 2), (3, 4), (5, 6)]. The pattern matching binds variables x and y to the corresponding parts of the pairs. The condition x + y >= 5 filters out pairs whose sum is less than 5. The resulting list comprehension will yield [(3, 4), (5, 6)], as they are the pairs that satisfy the condition.


Pattern matching in list comprehensions allows for powerful manipulation and filtering of lists by matching and extracting specific elements based on their structure. It is a concise and expressive feature in Haskell that leverages the functional programming paradigm.

Facebook Twitter LinkedIn Whatsapp Pocket

Related Posts:

Pattern matching is a powerful feature in Rust that allows you to destructure complex data structures and perform different actions based on the pattern of the data.To use pattern matching in Rust, you can use the match keyword followed by a series of patterns...
To call Haskell functions from Java, you can make use of the Java Native Interface (JNI). Here is a step-by-step explanation of how to do it:Write your Haskell code: Start by writing the Haskell functions you want to call from Java. The functions should be par...
Pattern matching in Rust is a powerful feature that allows you to match and destructure data structures such as enums, structs, tuples, and slices. It is primarily used in match expressions, function and closure arguments, and the let statement.To use pattern ...