簡體   English   中英

如何在Haskell中強制評估?

[英]How to force evaluation in Haskell?

我對Haskell相對較新,我正在嘗試學習如何使用符號按順序執行不同的操作。 特別是,我正在編寫一個程序來對算法進行基准測試(一個函數)

foo :: [String] -> [String]

為此,我想寫一個像這樣的函數

import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let r = foo inputList
                         end <- getCPUTime
                         return (end - start) -- Possible conversion needed.

最后一行可能需要轉換(例如,毫秒),但這不是這個問題的主題。

這是衡量在某個參數inputList上計算函數foo所需時間的正確方法嗎?

換句話說,在動作end <- getCPUTime執行之前,表達式foo inputList會完全減少? 或者r只能綁定到thunk foo inputList

更一般地說,如何在執行某些操作之前確保完全評估表達式?


這個問題幾個月前被問到程序員(見這里 )並在那里得到了一個可接受的答案,但它已被關閉為主題,因為它屬於堆棧溢出。 問題無法移動到堆棧溢出,因為它超過60天。 因此,與主持人達成一致意見,我在此處重新提出問題並自行發布已接受的問題,因為我認為它包含一些有用的信息。

最初由用戶ysdx給出的程序員答案:

實際上,您的版本不會對您的算法進 由於r未被使用,因此根本不進行評估。

您應該能夠使用DeepSeq

 benchmark :: [String] -> IO Integer benchmark inputList = do start <- getCPUTime let r = foo inputList end <- r `deepseq` getCPUTime return (end - start) 

a `deepseq` b )是一些“魔力”表達這迫使的完整/遞歸計算a返回之前b

我會使用語言擴展-XBangPatterns ,我覺得在這種情況下很有表現力。 所以你必須說“ let !r = foo inputList ”,如:

{-# LANGUAGE BangPatterns #-}
import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let !r = foo inputList
                         end <- getCPUTime
                         return (end - start)

暫無
暫無

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

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