給定以下函式
multThree :: (Num a) => a -> a -> a -> a
multThree x y z = x * y * z
以及這樣的描述:
當我們做
multThree 3 5 9或((multThree 3) 5) 9時,到底發生了什么?首先,3被應用于multThree,因為它們被一個空格分開。這創建了一個接受一個引數并回傳一個函式的函式。然后,5被應用于此,它創建了一個函式,它將接受一個引數并將其乘以15。9被應用于該函式,其結果是135或其他。記住,這個函式的型別也可以寫成multThree :: (Num a) => a -> (a -> (a -> a))。
我對此的解釋如下,我想確定這一點是正確的:
((multThree 3) 5) 9 =
((3*y*z)5) 9=
(15*z)9 =
15*9=9
=135
這是對本段所述的multThree功能的正確解釋嗎?
uj5u.com熱心網友回復:
你很接近,但你錯過了一個關鍵點。((3*y*z)5)9不是一個有效的表達。特別是,雖然multThree中的multThree 9是一個函式,但3*y*z(你用multThree代替的東西)不再是一個函式。(請注意,y和z沒有被定義就被使用)。) 為了解決這個問題,我們將重寫multThree為
multThree = (x -> (y -> (z -> x*y*z))
--或者去掉所有不必要的括號。
multThree = x -> y -> z -> x * y * z
現在你可以代入,所有的作業都可以完成:
multThree 3 5 9
= (x -> y -> z -> x * y * z) 3 5 9
= (y -> z -> 3 * y * z) 5 9
= (z -> 3 * 5 * z) 9
= 3 * 5 * 9
這也可能引起另一個問題,即乘法運算子(*)的評估順序。在我們的例子中,(*)是左聯想的:
Prelude> :info (*)
class Num a where
...
(*) :: a -> a -> a
...
--定義于`GHC.Num'。
infixl 7 *
也就是說,你的3 * 5 * 9實際上是(3 * 5)* 9。
uj5u.com熱心網友回復:
你忘了lambdas,否則你的解釋是正確的:
你忘了lambdas。
((multThree 3) 5) 9 =
((y z -> 3*y*z)5)9=
(z -> 15*z)9 =
15*9=9
=135
事實上,multThree 3是一個期望y和z,并回傳3*y*z的函式。我們把它寫成y z -> 3*y*z.
類似地,multThree 3 5是一個只期望z并回傳3*5*z的函式。我們把它寫成z -> 3*5*z.
最后multThree 3 5 9不再是一個函式,3*5*9。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/316914.html
標籤:
