繁体   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