Sunday, May 19, 2013

HASKELL CURRYING AND PARTIAL APPLICATION INTRODUCTION

HASKELL CURRYING AND PARTIAL APPLICATION INTRODUCTION

REVISED: Wednesday, January 24, 2024




Haskell currying and partial 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 APPLICATION

You get another function back when you underload or call a function with partial 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. 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.

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