ceno980
ceno980

Reputation: 2011

Haskell: Question about Partial Application

I am reading the book 'Learn You a Haskell for Great Good!' by Miran Lipovaca and learning about higher-order functions in Chapter 5.

One of the examples involves the following function:

applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)

The following are examples of the function's output:

ghci> applyTwice (++ " HAHA") "HEY"
"HEY HAHA HAHA"

ghci> applyTwice ("HAHA " ++) "HEY"
"HAHA HAHA HEY"

For the first example, I understand that the string was produced by using the concatenation operator in the following manner:

"HEY" ++ " HAHA"
"HEY HAHA" ++ " HAHA"
"HEY HAHA HAHA"

However, I don't understand how the concatenation operator works in the second example. How is the output string "HAHA HAHA HEY" produced? Any insights are appreciated.

Upvotes: 2

Views: 69

Answers (1)

TrebledJ
TrebledJ

Reputation: 8997

For the first example, I understand that the string was produced by using the concatenation operator in the following manner:

"HEY" ++ " HAHA"
"HEY HAHA" ++ " HAHA"
"HEY HAHA HAHA"

Instead of directly jumping to the infix expression (i.e. ++ is in between), it helps if you think in terms of functions.

(++ " HAHA") :: [Char] -> [Char]   -- #1 this is a function (++ is partially applied)     
"HEY" :: [Char]

(++ " HAHA") "HEY"                 -- apply "HEY" as an argument to #1
-- same as "HEY" ++ " HAHA"

(+) :: (Num a) => a -> a -> a      -- #2 a binary function
(+) 1 2                            -- #3 apply 1 and 2 as arguments to #2
-- same as 1 + 2

-- technically, #3 is curried as
--    ((+) 1) 2                    -- i.e. (+) 1 is a partially applied function, which is then applied to 2     

If you substitute (++ " HAHA") into the definition of applyTwice, you get

applyTwice f x = f (f x)
applyTwice (++ " HAHA") "HEY" = (++ " HAHA") ((++ " HAHA") "HEY")

                              = (++ " HAHA") ("HEY" ++ " HAHA")
                              = (++ " HAHA") ("HEY HAHA")
                              = "HEY HAHA" ++ " HAHA"
                              = "HEY HAHA HAHA"

Now do the same with applyTwice ("HAHA " ++) "HEY".

applyTwice f x = f (f x)
applyTwice ("HAHA " ++) "HEY" = ("HAHA " ++) (("HAHA " ++) "HEY")

                              = ("HAHA " ++) ("HAHA " ++ "HEY")
                              = ("HAHA " ++) ("HAHA HEY")
                              = "HAHA " ++ "HAHA HEY"
                              = "HAHA HAHA HEY"

Upvotes: 2

Related Questions