Haskell:有关部分申请的问题

时间:2019-06-04 03:40:11

标签: haskell functional-programming higher-order-functions partial-application

我正在读《为哈萨克学到伟大的东西!》这本书。由Miran Lipovaca撰写,并在第5章中学习了高阶函数。

其中一个示例涉及以下功能:

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

以下是函数输出的示例:

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

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

对于第一个示例,我了解到该字符串是通过以下方式使用串联运算符生成的:

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

但是,我不理解第二个示例中串联运算符的工作方式。如何产生输出字符串“ HAHA HAHA HEY”?任何见解都表示赞赏。

1 个答案:

答案 0 :(得分:3)

  

对于第一个示例,我了解到该字符串是通过以下方式使用串联运算符生成的:

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

如果您从函数的角度考虑,它会直接跳转到infix表达式(即介于++之间),而不会有所帮助。

(++ " 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     

如果将(++ " HAHA")替换为applyTwice的定义,则会得到

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

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

现在对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"