How to Use Higher-Order Functions In Haskell?

11 minutes read

In Haskell, higher-order functions are a fundamental concept that allows us to write more concise and modular code. They provide a way to take functions as arguments, return functions as results, or even both. Here is how you can use higher-order functions in Haskell:

  1. Passing functions as arguments: You can pass functions as arguments to other functions by declaring the argument type as a function type. For example: applyFunction :: (a -> b) -> a -> b applyFunction f x = f x In the above code, applyFunction takes a function f (of type a -> b) and an argument x (of type a), and applies the function f to x to get the result b. You can use this function with any other functions that have compatible argument and result types.
  2. Returning functions as results: You can also define functions that return other functions as results. This is particularly useful for creating functions with partially applied arguments. For example: multiplyBy :: Int -> (Int -> Int) multiplyBy x = \y -> x * y In the above code, multiplyBy takes an integer x and returns a lambda function that takes another integer y and multiplies it by x. This allows you to create specialized functions that are based on a common pattern but have different constant values.
  3. Combining multiple functions: Higher-order functions can also be used to combine or compose multiple functions together. For example, you can use the . operator to compose two functions. The resulting function applies the second function to the output of the first function. Here is an example: square :: Int -> Int square x = x * x tripleAndSquare :: Int -> Int tripleAndSquare = square . (* 3) In the above code, tripleAndSquare is a composition of square and the lambda function (* 3). It first triples the input value and then squares the result.


Higher-order functions in Haskell enable powerful abstractions and facilitate functional programming techniques. They help in writing more reusable, expressive, and concise code, making Haskell a highly expressive and elegant programming language.

Best Haskell Books to Read in 2024

1
Haskell in Depth

Rating is 5 out of 5

Haskell in Depth

2
Programming in Haskell

Rating is 4.9 out of 5

Programming in Haskell

3
Get Programming with Haskell

Rating is 4.8 out of 5

Get Programming with 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
Haskell from the Very Beginning

Rating is 4.6 out of 5

Haskell from the Very Beginning

6
The Haskell School of Expression: Learning Functional Programming through Multimedia

Rating is 4.5 out of 5

The Haskell School of Expression: Learning Functional Programming through Multimedia


How to use the map function with higher-order functions in Haskell?

In Haskell, the map function is a higher-order function that applies a given function to each element of a list. Here is how you can use the map function with higher-order functions in Haskell:

  1. Define a function that you want to apply to each element of a list. For example, let's say you want to multiply each element of a list by 2. You can define a function called double as follows:
1
2
double :: Int -> Int
double x = x * 2


  1. Use the map function to apply the defined function to each element of a list. The syntax for using the map function is map functionName list. For example, to apply the double function to each element of a list called numbers, you can use the following code:
1
2
numbers = [1, 2, 3, 4, 5]
doubledNumbers = map double numbers


In this code, the map function takes the double function and the numbers list as arguments and returns a new list called doubledNumbers.


The result of the map function in this example would be [2, 4, 6, 8, 10], as each element of the numbers list is multiplied by 2.


Note that the function you provide to the map function can also be an anonymous lambda function. Here's an example using a lambda function:

1
2
numbers = [1, 2, 3, 4, 5]
doubledNumbers = map (\x -> x * 2) numbers


This code achieves the same result as the previous code snippet, but it uses a lambda function instead of a named function.


How to create a higher-order function that takes multiple arguments in Haskell?

In Haskell, a higher-order function can be created that takes multiple arguments using currying or by using tuples. Here are examples of both methods:

  1. Currying: Currying is the process of transforming a function that takes multiple arguments into a series of functions that take one argument each. Here's an example of creating a higher-order function that takes two arguments:
1
2
3
4
5
6
7
8
9
mult :: Int -> Int -> Int
mult x y = x * y

higherOrderFunc :: (Int -> Int -> Int) -> Int -> Int
higherOrderFunc f x = f x 10

-- Usage:
-- ghci> higherOrderFunc mult 5
-- 50


In the above example, the higherOrderFunc takes a function f as the first argument, which takes two integers and returns an integer. It then applies the function f to the x argument (here, multiplied by 10).

  1. Using Tuples: Tuples can be used to pass multiple arguments to a higher-order function. Here's an example:
1
2
3
4
5
6
7
8
9
add :: (Int, Int) -> Int
add (x, y) = x + y

higherOrderFunc :: ((Int, Int) -> Int) -> (Int, Int) -> Int
higherOrderFunc f args = f args

-- Usage:
-- ghci> higherOrderFunc add (5, 10)
-- 15


In the above example, the higherOrderFunc takes a function f as the first argument, which takes a tuple (Int, Int) as an argument and returns an integer. It then passes the args tuple to the function f.


How to use the filter function with higher-order functions in Haskell?

In Haskell, the filter function is a higher-order function that takes a predicate (a function that returns a Boolean value) and a list as arguments, and returns a new list that contains only the elements for which the predicate returns True.


Here is the general syntax for using the filter function in Haskell:

1
filter :: (a -> Bool) -> [a] -> [a]


To use the filter function with higher-order functions in Haskell, you can pass it a lambda function or a named function that acts as the predicate. Here are a few examples:

  1. Using a lambda function:
1
filter (\x -> x `mod` 2 == 0) [1,2,3,4,5,6]  -- Output: [2,4,6]


In this example, the lambda function \x -> x mod 2 == 0 acts as the predicate. It checks if an element is divisible by 2 (i.e., even).

  1. Using a named function:
1
2
3
4
isPositive :: Int -> Bool
isPositive x = x > 0

filter isPositive [-2,-1,0,1,2,3]  -- Output: [1,2,3]


In this example, the named function isPositive acts as the predicate. It checks if an element is greater than 0.


Both of these examples demonstrate how to use the filter function with higher-order functions in Haskell. Simply define a predicate function and pass it as the first argument to the filter function along with the list as the second argument.


What is the purpose of the filter function in Haskell?

The filter function is used in Haskell to selectively extract elements from a list that satisfy a given condition. Its purpose is to take a predicate (a function that evaluates to a Boolean value) and a list, and return a new list containing only the elements for which the predicate returns true.


The general type signature of the filter function is:


filter :: (a -> Bool) -> [a] -> [a]


It takes a predicate function of type (a -> Bool), where 'a' is the type of elements in the list, and a list of type [a]. The resulting list is also of type [a].


For example, if we have a list of numbers [1, 2, 3, 4, 5] and want to filter out only the even numbers, we can define a predicate function using the modulus operator:


evenNum :: Int -> Bool evenNum x = x mod 2 == 0


Using the filter function with this predicate:


filter evenNum [1, 2, 3, 4, 5]


will return the list [2, 4]. The filter function goes through each element of the list, applies the predicate function to it, and includes it in the resulting list if the predicate returns true.


In essence, the purpose of the filter function is to provide a concise and functional way of extracting elements from a list based on a condition. It helps in writing more expressive and readable code.


How to use the foldr function with higher-order functions in Haskell?

In Haskell, the foldr function is used to apply a binary function to a list from right to left, reducing it to a single value. It takes three arguments: the binary function, the initial accumulator value, and the list to be folded.


Here is an example of how to use foldr with higher-order functions in Haskell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
-- Example 1: Summing a list of numbers using foldr
sumList :: [Int] -> Int
sumList xs = foldr (+) 0 xs

-- Example 2: Concatenating a list of strings using foldr
concatList :: [String] -> String
concatList xs = foldr (++) "" xs

-- Example 3: Filtering odd numbers from a list using foldr and a lambda function
filterOdd :: [Int] -> [Int]
filterOdd xs = foldr (\x acc -> if odd x then x : acc else acc) [] xs


In these examples:

  • sumList uses foldr with the addition operator (+) and an initial accumulator value of 0 to calculate the sum of a list of Ints.
  • concatList uses foldr with the string concatenation operator (++) and an initial accumulator value of "" to concatenate a list of strings.
  • filterOdd uses foldr with a lambda function as the binary operator to filter odd numbers from a list. The lambda function takes an element x and an accumulator acc and checks if x is odd. If x is odd, it is prepended to the accumulator acc; otherwise, acc is returned without modification.


You can use foldr with other higher-order functions in a similar fashion by passing appropriate binary functions and initial accumulator values.

Facebook Twitter LinkedIn Telegram Whatsapp Pocket

Related Posts:

Getting a date in Haskell involves writing code to handle date and time-related operations. While Haskell is primarily a functional programming language, it provides libraries and functions to work with dates and times.To get a date in Haskell, you can use the...
In Haskell, several functions involve caching to improve performance. These include:Memoization: Haskell provides an easy way to memoize functions, which involves caching the results of function calls for subsequent invocations with the same input parameters. ...
In Haskell, exceptions are handled using a mechanism called "pure exceptions." Unlike in most imperative languages, where exceptions can be thrown and caught at any point in the execution flow, Haskell promotes a pure and functional approach to managin...