gpt4 book ai didi

haskell - 在 Haskell 中计算期间只执行一次副作用

转载 作者:行者123 更新时间:2023-12-02 02:23:13 24 4
gpt4 key购买 nike

假设我们想要一个按需计算的值的集合(计算有一些副作用),并且在您再次访问它们时不会再次重新计算。
以下两种幼稚的方法将不起作用:

Prelude> let f x = print x >> return x
Prelude> let a = map f "abc"
Prelude> :t a
a :: [IO Char]
Prelude> head a
'a'
'a'
Prelude> head a
'a'
'a'
Prelude> let b = mapM f "abc"
Prelude> :t b
b :: IO [Char]
Prelude> fmap head b
'a'
'b'
'c'
'a'
Prelude> fmap head b
'a'
'b'
'c'
'a'
我该如何正确地做到这一点?截至目前,我什至不明白集合应该有什么类型。

最佳答案

这是一个使用 IORef 缓存值的小型库。 .函数cache下面转换 IO a进入另一个 IO a它只会执行一次副作用,并在下次执行时返回缓存值。

import Data.IORef

cache :: IO a -> IO (IO a)
cache action = do
v <- newIORef Nothing
return $ do
x <- readIORef v
case x of
Nothing -> do
res <- action
writeIORef v $ Just res
return res
Just res -> return res
这是你的功能:
f :: Char -> IO Char
f x = print x >> return x
这是一个小例子,展示了如何使用 cache .
main :: IO ()
main = do
acts <- mapM (cache . f) "abc"
-- here we have acts :: [IO Char]
putStrLn "1st: "
head acts -- prints 'a'
putStrLn "2nd: "
head acts -- prints nothing
putStrLn "3rd: "
head acts -- prints nothing
return ()
只有第一个调用打印 'a'在屏幕上。

关于haskell - 在 Haskell 中计算期间只执行一次副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63535881/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com