簡體   English   中英

函數評估在Haskell中如何工作

[英]How does function evaluation work in Haskell

我覺得我的函數式編程的知識是欠缺所以有點我決定去看看網上,並按照教程,以獲得更好,當我遇到凸輪這個地方的第一頁上指出

“假設您有一個不變的數字xs = [1,2,3,4,5,6,7,8]列表,以及一個doubleMe函數,該函數將每個元素乘以2,然后返回一個新列表。如果我們想乘以我們用命令式語言將列表乘以8,然后執行doubleMe(doubleMe(doubleMe(doubleMe(xs)))),它可能會通過列表一次,然后進行復制然后返回,然后再通過列表兩次,然后返回結果。”

根據我對函數式編程的了解,這似乎是錯誤的,讓我向您展示原因:

doubleMe = (\x.* 2 x)

所以

doubleMe doubleMe doubleMe xs

Beta會減少為:

(\x.* 2 x) doubleMe doubleMe xs ->beta
(* 2 doubleMe) doubleMe xs 
(* 2 (\x.* 2 x)) doubleMe xs ->eta
(\x.* 2 * 2 x) doubleMe  xs ->beta
(* 2 * 2 doubleMe)  xs
(* 2 * 2 (\x.* 2 x)) xs ->eta
(\x.* 2 * 2 * 2 x) xs ->beta
(* 2 * 2 * 2 xs) ->beta
(* 4 * 2 xs) -> beta
(* 8 xs)

這意味着該函數的beta與(\\ x。* 8 x)等價

我給人的印象是,Haskell編譯器在執行之前進行了這種簡化,這意味着不,它不會像本教程所建議的那樣在列表上進行3次傳遞,而只會進行一次。 我錯了嗎? 如果是這樣,那么Haskell為什么不這樣做? 當然,它將大大改善性能。

我認為您只是誤讀了該段。 它說(強調我的):

如果我們想使用命令式語言將列表乘以8並doubleMe(doubleMe(doubleMe(xs))) ,則它可能會通過列表一次,然后進行復制然后返回。

命令式語言是諸如C或Python之類的語言。 不是Haskell。

該段繼續將這種行為與“惰性語言”的行為進行對比:

用一種懶惰的語言...它只會在您真正需要時通過列表。 這樣,當您想從懶惰的語言中獲取某些東西時,您只需獲取一些初始數據並有效地進行轉換和修補,使其類似於最終所需的內容。

哪個更接近您的期望。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM