使用爆炸模式时,IO monad是否变得严格?

问题描述 投票:1回答:1

我期望以下代码段:

main = do
    let !x = [2,3,5,2,3,5,6,7,1,3,0,1]
    begin <- getCPUTime
    let !rx = reverse x
    end <- getCPUTime
    putStrLn $ "Calculation time: " ++ show (end - begin) ++ " ps."
    putStrLn $ "Result: " ++ show rx

与以下版本相同:

main = do
    let x = [2,3,5,2,3,5,6,7,1,3,0,1]
    begin <- x `seq` getCPUTime
    let rx = reverse x
    end <- rx `seq` getCPUTime
    putStrLn $ "Calculation time: " ++ show (end - begin) ++ " ps."
    putStrLn $ "Result: " ++ show rx

这是真的吗?如果在第一个版本中,xrx在“需要”时评估为WHNF,则为false。

顺便说一句,我想提出一种用于深度评估的语法糖,名为“双爆炸模式”。

haskell io monads lazy-evaluation syntactic-sugar
1个回答
2
投票

您提供的特定代码示例将生成相同的编译代码。如果您采用以下程序:

{-# LANGUAGE BangPatterns #-}

module Bang where

import System.CPUTime

main1 = do
    let !x = [2,3,5,2,3,5,6,7,1,3,0,1]
    begin <- getCPUTime
    let !rx = reverse x
    end <- getCPUTime
    putStrLn $ "Calculation time: " ++ show (end - begin) ++ " ps."
    putStrLn $ "Result: " ++ show rx

main2 = do
    let x = [2,3,5,2,3,5,6,7,1,3,0,1]
    begin <- x `seq` getCPUTime
    let rx = reverse x
    end <- rx `seq` getCPUTime
    putStrLn $ "Calculation time: " ++ show (end - begin) ++ " ps."
    putStrLn $ "Result: " ++ show rx

并使用(GHC版本8.6.5)进行编译:

stack ghc -- -dsuppress-all -dsuppress-uniques -ddump-simpl -fforce-recomp -O2 Bang.hs

您将在转储的GHC内核中发现main1main2被编译为完全相同的代码,实际上它们被拉出到单独的main4函数中:

main1
main1 = main4 `cast` <Co:3>

main2
main2 = main4 `cast` <Co:3>

HOWEVER,通常,let !x = ...构造与使用let x = ...后接x `seq` y并不完全等效。例如,以下两个IO操作是不同的:

foo :: IO ()
foo = do
  let !x = undefined
  return ()

bar :: IO ()
bar = do
  let x = undefined
  return $ x `seq` ()

第一个立即产生异常:

main = do
    print 1
    foo       -- EXCEPTION!
    print 2

第二个命令在执行时不执行任何操作,但如果您尝试检查其结果,则会产生异常:

main = do
    print 1
    bar        -- does nothing
    print 2
    x <- bar   -- also does nothing
    print 3
    () <- bar  -- EXCEPTION!
    print 4

[我相信,退避三舍之后,barfoo等效于:

bar = return (undefined `seq` ())
foo = undefined `seq` return ()

这说明了他们的不同行为。

© www.soinside.com 2019 - 2024. All rights reserved.