Showing posts with label Functional programming. Show all posts
Showing posts with label Functional programming. Show all posts

Thursday, June 1, 2023

HASKELL IS A TOOL

HASKELL MONAD OVERVIEW

REVISED: Monday, October 7, 2024


1. INTRODUCTION

Haskell is a powerful programming language that is well-suited for a variety of tasks.

2. OVERVIEW

For example Haskell is well-suited for tasks including:

Functional programming: Haskell is a purely functional language, which means that it does not have side effects. This makes it ideal for tasks that require a high degree of mathematical precision, such as symbolic computation and artificial intelligence.

Concurrent programming: Haskell has built-in support for concurrent programming, which makes it ideal for tasks that require multiple threads of execution, such as web servers and distributed systems.

Data analysis: Haskell has a rich set of libraries for data analysis, making it ideal for tasks such as data mining and machine learning.

However, Haskell is not without its drawbacks. It can be difficult to learn, and it is not as widely used as other programming languages, such as Java and Python. This can make it difficult to find help and resources when you are using Haskell.

Here are some tasks that are better suited for other programming languages:

Web development: Haskell is not a good choice for web development. There are few web frameworks available for Haskell, and the language's performance can be a bottleneck for high-traffic websites.

Graphics programming: Haskell is not a good choice for graphics programming. The language does not have built-in support for graphics libraries, and its performance can be a bottleneck for graphics-intensive applications.

Game development: Haskell is not a good choice for game development. The language does not have built-in support for game engines, and its performance can be a bottleneck for games with complex graphics and physics.

3. CONCLUSION

Overall, Haskell is a powerful programming language that is well-suited for a variety of tasks. However, it is important to choose the right tool for the job. If you are working on a task that requires a high degree of mathematical precision, concurrent programming, or data analysis, then Haskell is a good choice. However, if you are working on a task that is better suited for a different programming language, then you should choose that language instead.

4. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.

Sunday, May 26, 2013

HASKELL GHCI DEBUGGER INTRODUCTION

HASKELL GHCI DEBUGGER INTRODUCTION

REVISED: Thursday, February 8, 2024




Haskell GHCi debugger.

I. HASKELL GHCI DEBUGGER

Even though lazy evaluation makes it difficult to apply traditional procedural debugging techniques to Haskell, GHCi contains a simple imperative-style debugger which can stop a running computation in order to examine the values of variables. However, breakpoints and single-stepping are only available in interpreted modules; compiled code is invisible to the debugger.

:sprint can be used to see lazy evaluation by telling you if a variable has been evaluated.

GHCi, version 9.8.1: http://www.haskell.org/ghc/  :? for help
Prelude>

Prelude>
let x = 1 + 2 :: Int
Prelude>

Prelude>
:sprint x
x = _  -- Lazy evaluation; therefore, x has not been computed.
Prelude>

Prelude>
x
3 -- A value has been requested for x.
Prelude>

Prelude> :sprint x
x = 3 -- Now Haskell shows a value for x.
Prelude>

A. SAMPLE PROGRAM TO DEBUG

Save the following module as Main.hs to your working directory:

module Main where

import System.IO
import Data.Char(toUpper)

main :: IO ()
main = do 
       inh <- openFile "input.txt" ReadMode
       outh <- openFile "output.txt" WriteMode
       mainloop inh outh
       hClose inh
       hClose outh

mainloop :: Handle -> Handle -> IO ()
mainloop inh outh = 
    do ineof <- hIsEOF inh
       if ineof
           then return ()
           else do inpStr <- hGetLine inh
                        hPutStrLn outh (map toUpper inpStr)
                        mainloop inh outh

Then open GHCi and :load Main.hs as shown below:

Prelude>  :load Main
[1 of 1] Compiling Main             ( Main.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

B. BREAKPOINTS

The GHCi debugger enables dynamic breakpoints and intermediate values observation.

The GHCi debugger provides a way of inspecting code. :b N sets a break point in the loaded module at a specific line. When a breakpoint is set on a particular line, GHCi sets the breakpoint on the leftmost subexpression that begins and ends on that line.

As shown below, breakpoints can be set many different ways. For example, by line; by line and column; by module; by module and line; and by module line and column.

:break line
:break line column
:break module
:break module line
:break module line column

Prelude>  :show breaks
No active breakpoints.
Prelude>

An example of setting a ":break module" breakpoint is shown below:

Prelude>  :break mainloop
Breakpoint 0 activated at Main.hs:(15,1)-(21,35)
Prelude>

As shown above the module mainloop starts on (15,1) line 15 column 1 and ends on (21,36) line 21 column 36.

Prelude>  :show breaks
[0] Main Main.hs:(15,1)-(21,35)
Prelude>

Prelude>  :delete *                      -- To delete all breakpoints at once.
Prelude>

Prelude>  :show breaks
No active breakpoints.
Prelude>    

When stopped at a breakpoint or single-step, GHCi binds the variable _result to the value of the currently active result expression. 

To delete a breakpoint, use the :delete <number> command with the number given in the output from :show breaks.

:list is used to list the source code around the current breakpoint.

:trace  can be used once you have hit a breakpoint, to continue to the next breakpoint, recording the history as you go along.

The following first outputs the message then returns the value of f x.

trace :: String -> a -> a
trace ("calling f with x = " ++ show x) (f x)

The trace function outputs the trace message given as its first argument, before returning the second argument as its result.

:back and :forward allow you to go up and down the list of evaluated expressions and inspect each one.

C. EXAMPLES

As shown below, GHCi uses the flag -fbreak-on-exception to allow you to break into program execution at an arbitrary point.

Prelude>  :set -fbreak-on-exception
Prelude>  

Prelude>  import Debug.Trace
Prelude>

Prelude>  :trace main
Stopped at <exception thrown>
_exception :: e = _
Prelude>

Prelude>  :list
Unable to list source for <exception thrown>
Try :back then :list
Prelude>

Prelude>  :back
Logged breakpoint at Main.hs:19:30-41
_result :: IO String
inh :: Handle
Prelude>

Prelude>  :list
18             then return () 
19             else do inpStr <- hGetLine inh                                  
20                     hPutStrLn outh (map toUpper inpStr) 
Prelude>

Prelude>  :hist
-1  : mainloop (Main.hs:19:30-41)
-2  : mainloop (Main.hs:(17,8)-(21,36))
-3  : mainloop (Main.hs:16:17-26)
-4  : mainloop (Main.hs:(16,5)-(21,36))
-5  : mainloop (Main.hs:(15,1)-(21,36))
-6  : main (Main.hs:10:8-24)
-7  : main (Main.hs:9:16-46)
<end of history>
Prelude>    

II. CONCLUSION

In this tutorial, you have been introduced to the Haskell GHCi debugger.

III. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.


Tuesday, May 21, 2013

HASKELL FUNCTION COMPOSITION

HASKELL FUNCTION COMPOSITION

REVISED: Tuesday, September 23, 2024




Haskell function composition.

I. HASKELL FUNCTION COMPOSITION

There are two main operations we can do with function values: apply them, and compose them. Haskell's laziness gives us compositionality.

The nesting of two or more functions to form a single new function is known as composition.

f (g x) = (f . g) x

Read as f of g is the composition of f with g.

The composition of f and g is a function that first applies g to its argument, then f to the value returned by g. It then returns the return value of f.

The primary purpose of the Haskell function composition . dot operator is to chain functions of the same type. It lets us tie the output of whatever appears on the right of the dot operator to the input of whatever appears on the left of the dot operator as long as they are of the same type.

The programming style of function composition, is called "pointfree" style, which means the arguments to the function are omitted. In many cases this makes for clearer code. Function composition is a common Haskell idiom. It is very common for functional programmers to write functions as a composition of other functions of the same type, never mentioning the actual arguments they will be applied to.

Pointfree style is often referred to as "pointless" style.

Composition is associative; for example, when more than two numbers are added or multiplied, the result remains the same, irrespective of how they are grouped.

EXAMPLE 1

λx.(3 + 4 * x) `div` 3
=
\x -> (3 + 4 * x) `div` 3

Prelude>  let y x = (3 + 4 * x) `div` 3
y :: Integral a => a -> a
Prelude>

Prelude>  y 3   -- Means x == 3
5
it :: Integral a => a
Prelude>

Prelude>  let y x = (`div` 3) (3 + 4 * x)
y :: Integral a => a -> a
Prelude>

Prelude>  y 3
5
it :: Integral a => a
Prelude>  

Prelude> let y = (`div` 3) . (+ 3) . (* 4)
y :: Integral c => c -> c
Prelude>

Prelude>  y 3
5
it :: Integral c => c
Prelude>  

Step 1:
(* 4) -- Means 3 * 4
12

Step 2:
(+ 3) . (* 4)  -- Means 12 + 3
15

Step 3:
(`div` 3)  -- Means 15 `div` 3
5

EXAMPLE 2


Prelude>  let y = take 3 (reverse (filter even [1..10]))  -- Using ( ) instead of $
y :: Integral a => [a]
Prelude>

Prelude>  y
[10,8,6]
it :: Integral a => [a]
Prelude>  

Prelude>  let y = take 3 . reverse . filter even [1..10]  -- With no $ [1..10] 

<interactive>:33:28:
    Couldn't match expected type ‘a -> [a1]’ with actual type ‘[a0]’
    Relevant bindings include
      y :: a -> [a1] (bound at <interactive>:33:5)
    Possible cause: ‘filter’ is applied to too many arguments
    In the second argument of ‘(.)’, namely ‘filter even [1 .. 10]’
    In the second argument of ‘(.)’, namely
      ‘reverse . filter even [1 .. 10]’
Prelude>  

The dot operator expects its second argument to be a function of one argument, not a list.

Prelude>  :type (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Prelude> 

Prelude>  :info (.)
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base'
infixr 9 .  -- Priority of 9.
Prelude>   

Function application has priority of 10, while function composition has a lower priority of 9. Therefore, we need the $ operator to allow function composition to evaluate first.

Prelude>  let y = take 3 . reverse . filter even $ [1..10]
y :: Integral a => [a]
Prelude>

Prelude>  y
[10,8,6]
it :: Integral a => [a]
Prelude> 

Step 1:
Prelude> filter even $ [1..10]
[2,4,6,8,10]
Prelude>

Step 2:
Prelude> reverse [2,4,6,8,10]
[10,8,6,4,2]
Prelude>

Step 3:
Prelude> take 3 [10,8,6,4,2]
[10,8,6]
Prelude>

II. CONCLUSION

In this tutorial, you have seen examples of  the associative nature of Haskell function composition.

III. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.



Sunday, May 19, 2013

HASKELL BINDING AND SCOPE INTRODUCTION

HASKELL BINDING AND SCOPE INTRODUCTION

REVISED: Wednesday, October 2, 2024




Haskell binding and scope.

Local bindings are values inside of a function that only that function can see.

I. HASKELL BINDING AND SCOPE

A. HASKELL BINDING AND SCOPE EXAMPLES

1. Variables in a Haskell where clause

The function fA1, shown below, is defined at the top level; and its scope is the program, it can be used anywhere in the program.

The scope of the functions y and z, shown below, is the function fA1; they have no value outside of the function fA1

The scope of the variable x is the function fA1 which includes the where clause; x has no value outside of the function fA1.  The variable x only has meaning while the function fA1 is being applied to the variable x.

fA1 :: Num a => a -> a
fA1 x = z
      where
      y = x + 1
      z = x + y * y

Prelude>  :load fA1
[1 of 1] Compiling Main             ( fA1.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  fA1 2
11
it :: Num a => a
Prelude>

Steps:
fA1 2
y = x + 1 therefore 
y  = 2  + 1 = 3
z = x + y * y therefore
z = 2 + 3 * 3 = 11

2. Functions in a Haskell where clause

The function fA2 is defined at the top level; and its scope is the program, it can be used anywhere in the program.

The scope of the function g is the function fA2; g has no value outside of the function fA2.

The scope of the variable x is the function fA2 which includes the where clause; x has no value outside of the function fA2

The scope of the variable y is the function g; y has no value outside of the function g.

fA2 :: Num a => a -> a
fA2 x = g (x+1)   -- Actual implied y is (x + 1).
      where
      g y = x+y*y   -- Formal y is bound to actual (x + 1).

Prelude>  :load fA2
[1 of 1] Compiling Main             ( fA2.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  fA2 2
11
it :: Num a => a
Prelude>  

Steps:
fA2 2
fA2 x = g (x+1) therefore
fA2 2 = g (2+1) = g (3)   -- Actual implied y
g y = x+y*y
g 3 = 2 + 3 * 3 = 11

3. Haskell lambda functions

Below are two lambda functions, their x variables do not share scope. An x variable in one lambda function is not the same x variable in the other lambda function.

Binding occurrence of function x.

Binding occurrence of function x.

fA3 :: [Int] -> [Int]
fA3 xs = map (\x -> x*x) (filter (\x -> x >0) xs)

Prelude>  :load fA3
[1 of 1] Compiling Main             ( fA3.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  fA3 [1,2,-3]
[1,4]
it :: [Int]
Prelude>  

II. CONCLUSION

In this tutorial, you have been introduced to Haskell binding and scope.

III. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.



HASKELL CURRYING AND PARTIAL FUNCTION APPLICATION INTRODUCTION

HASKELL CURRYING AND PARTIAL APPLICATION INTRODUCTION

REVISED: Tuesday, October 15, 2024




Haskell currying and partial function application.

I. HASKELL CURRYING

Haskell only allows functions of one argument.

Haskell defines multiple argument functions in terms of functions of one argument.

For example, a function of two arguments is the same as a function of the first argument that returns a function of the second argument.

A. HASKELL CURRYING EXAMPLES

1. Haskell add currying

-- add takes an Int and returns a function.
add :: Int -> (Int -> Int)
(add x) y = x + y

GHCi, version 9.8.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>

Prelude>  let add x y = x + y
add :: Num a => a -> a -> a
Prelude>

Call the function add in GHCi as follows:

Prelude>  add 3 4
7
it :: Num a => a
Prelude>  

(add 3) 4   -- add of 3 is a function applied to 4.
=
3 + 4
=
7

"Copy Paste" the following function into your text editor and "File, Save As" mysum.hs to your working directory:

mysum :: [Int] -> Int
mysum = foldr add 0
    where
    add x y = x + y

Prelude>  :load mysum
[1 of 1] Compiling Main             ( mysum.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Call the function mysum in GHCi as follows:

Prelude>   mysum [3,4]
7
it :: Int
Prelude>  

2. Haskell product currying examples

"Copy Paste" the following function into your text editor and "File, Save As" myproduct.hs to your working directory:

myproduct :: [Int] -> Int
myproduct = foldr times 1
    where
    times x y = x * y

Load the function myproduct into GHCi as follows:

Prelude>  :load myproduct
[1 of 1] Compiling Main             ( myproduct.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Call the function myproduct in GHCi as follows:

Prelude>  myproduct [5,6]
30
it :: Int
Prelude>  

"Copy Paste" the following function into your text editor and "File, Save As" f2a.hs to your working directory:

f2a :: [Int] -> Int
f2a xs = foldr (+) 0 (map sqr (filter pos xs))
      where
      sqr x = x * x
      pos x = x > 0

GHCi, version 9.8.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>

Load the function f2a into GHCi as follows:

Prelude>  :load f2a
[1 of 1] Compiling Main             ( f.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Call the function f2a in GHCi as follows:

Prelude>  f2a [1,-2,3]
10
it :: Int
Prelude>  

"Copy Paste" the following function into your text editor and "File, Save As" f2b.hs to your working directory:

f2b :: [Int] -> Int
f2b xs = foldr (+) 0
      (map (\x -> x * x)
          (filter (\x -> x > 0) xs))

Load the function f2b into GHCi as follows:

Prelude>  :load f2b
[1 of 1] Compiling Main             ( f.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Call the function f2b in GHCi as follows:

Prelude>  f2b [1,-2,3]
10
it :: Int
Prelude>  

3. Haskell concat currying

"Copy Paste" the following function into your text editor and "File, Save As" myConcat.hs to your working directory:
    
myConcat :: [[a]] -> [a]
myConcat = foldr append []
     where
     append xs ys = xs ++ ys

Load myConcat into GHCi as follows:

Prelude>  :load myConcat
[1 of 1] Compiling Main             ( myConcat.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Call the function myConcat in GHCi as follows:

Prelude>  myConcat [['a','b','c'],['A','B','C']]
"abcABC"
it :: [Char]
Prelude> 

II. PARTIAL FUNCTION APPLICATION

You get another function back when you underload or call a function with a partial function application of only some of its arguments.

A higher-order function can take functions as parameters and return functions as return values.

Consider, for example:

module PartialApplication where

main = do
    let partialApplication x y z = x + y + z
    let add5 = partialApplication 5
    add5 6 7

Load PartialApplication.hs into GHCi:

Prelude>  :load PartialApplication
[1 of 1] Compiling PartialApplication ( PartialApplication.hs, interpreted )
Ok, modules loaded: PartialApplication.
Prelude>

Call the function main:

Prelude>  main
18
Prelude>

III. CONCLUSION

In this tutorial, you have been introduced to Haskell currying and partial function application.

IV. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.




Saturday, May 18, 2013

HASKELL FOLDR INTRODUCTION

HASKELL FOLDR INTRODUCTION

REVISED: Friday, October 25, 2024




Haskell foldr.

I. HASKELL FOLDR

foldr simultaneously replaces each (:) in a list by a given function, and [] by a given value:

sum       = foldr   (+)      0
product = foldr   (*)      1
or          =  foldr   (||)      False
and       =  foldr   (&&)  True

A. HASKELL FOLDR EXAMPLES

1. Generic Haskell foldr

foldr :: (a -> a -> a) -> a -> [a] -> a
foldr f a []        = a
foldr f a (x:xs) = f x (foldr f a xs)

Prelude>  foldr (+) 50 [10,20,30,40]
150
it :: Num a => a
Prelude>

foldr begins at the right-hand end of the list and combines each list entry with the accumulator value using the function you give it. The result is the final value of the accumulator after "folding" in all the list elements.

(10 + (20 + (30 + (40 + 50))))

The above is the same as:

40 +   50 =   90
30 +   90 = 120 
20 + 120 = 140
10 + 140 = 150

2. Haskell foldr sum

mysum :: [Int] -> Int
mysum xs = (foldr add) (0 xs)  -- 0 is the sum identity for [].
    where
    add x y = x + y

mysum [1,2,3,4]
=
foldr add 0 [1,2,3,4]
=
(add 1 (add 2 (add 3 (add 4 0))))
=
(1 + (2 + (3 + (4 + 0))))
=
10

Prelude>  :load mysum
[1 of 1] Compiling Main             ( mysum.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  mysum [1,2,3,4]   -- Prelude has a sum function.
10
Prelude> 

4 + 0 =   4
3 + 4 =   7
2 + 7 =   9
1 + 9 = 10

3. Haskell foldr product

product :: [Int] -> Int
product xs = foldr times 1 xs  -- 1 is product identity for [].
    where
    times x y = x * y

4. Haskell foldr concat

concat :: [[a]] -> [a]
concat xs = foldr append [] xs  -- empty list [] for append.
    where
    append xs ys = xs ++ ys

5. Haskell map filter and foldr sum of squares of positives

"Copy Paste" the following function into your text editor and "File, Save As" f5.hs to your working directory:

f5 :: [Int] -> Int
f5 xs = foldr add 0 (map square (filter positive xs))
    where
    add x y     = x + y
    square x   = x * x
    positive x = x > 0

Load the above function into GHCi as follows:

Prelude>  :load f5
[1 of 1] Compiling Main             ( f5.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  :type f5
f :: [Int] -> Int
Prelude>

From GHCi call function f5 as follows:

Prelude>  f5 [1,-2,3,-4]
10
it :: Int
Prelude>  

-4 > 0 = False
 3 >  0 = True          3 ^ 2 = 9
-2 > 0 = False
 1 >  0 = True          1 ^ 2 = 1    

9 + 0 =   9
1 + 9 = 10

Think of foldr non-recursively as simultaneously replacing each (:) in a list by a given function, and [] by a given value. In other words, for each constructor it applies a certain function.

Given := is read as, "is replaced by."

xs [ (:) := f, [] := v]

For example:

{-
Replace each (:) with (+) and [] with 0.

sum [4,5,6]

foldr (+) 0 [4,5,6]
=
-- foldr (+) 0 (4:(5:(6:[])))
-- =
4+(5+(6+0))
=
15
-}

As shown below, the choice between foldr and foldl could make a difference:

Prelude>  foldr (div) 70 [340,560,120,40,230]
5
Prelude>  

Prelude>  (340 / (560 / (120 / (40 / (230 / 70)))))
5.9846938775510194
Prelude> 

Prelude>  foldl (div) 70 [340,560,120,40,230]
0
Prelude>

Prelude>  (((((340/70)/560)/120)/40)/230)
7.856403430937593e-9
Prelude>  

6. REVERSE

Prelude>  let reverse = foldr (\x -> \xs -> xs ++ [x]) []
Prelude>

Prelude>  :type reverse
reverse :: [a] -> [a]
Prelude>

Prelude>  reverse [1,2,3]
[3,2,1]
Prelude>  

7. FACTORIAL

fac :: (Num b, Enum b) => b -> b
fac n = foldr (*) 1 [1..n]

Prelude>  :load fac
[1 of 1] Compiling Main             ( fac.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  fac 3
6
Prelude>

(1 * (2 * (3 * 1)))

The above is the same as:

3 * 1 = 3
2 * 3 = 6
1 * 6 = 6

II. CONCLUSION

In this tutorial, you have been introduced to some of the advantages and disadvantages of using Haskell foldr.

III. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.