gpt4 book ai didi

haskell - 内存IO功能?

转载 作者:行者123 更新时间:2023-12-03 14:42:49 26 4
gpt4 key购买 nike

只是好奇如何重写以下函数,使其在程序生命周期内仅被调用一次?

getHeader :: FilePath -> IO String
getHeader fn = readFile fn >>= return . take 13

上述函数从各种函数中被多次调用。
如果使用相同的参数调用函数,即如何防止重新打开文件。文档名称 ?

最佳答案

我鼓励你寻求一个更实用的解决方案,例如通过预先加载你需要的头文件并将它们传递到一些数据结构中,例如 Map .如果显式传递它不方便,您可以使用 ReaderState monad 变压器来为你处理。

也就是说,您可以通过使用 unsafePerformIO 以您想要的方式完成此操作。创建一个全局可变引用来保存您的数据结构。

import Control.Concurrent.MVar
import qualified Data.Map as Map
import System.IO.Unsafe (unsafePerformIO)

memo :: MVar (Map.Map FilePath String)
memo = unsafePerformIO (newMVar Map.empty)
{-# NOINLINE memo #-}

getHeader :: FilePath -> IO String
getHeader fn = modifyMVar memo $ \m -> do
case Map.lookup fn m of
Just header -> return (m, header)
Nothing -> do header <- take 13 `fmap` readFile fn
return (Map.insert fn header m, header)

我使用了 MVar这里是为了线程安全。如果您不需要它,您可以使用 IORef 逃脱。反而。

另外,请注意 NOINLINE pragma on memo以确保引用只创建一次。如果没有这个,编译器可能会将它内联到 getHeader ,每次都给你一个新的引用。

关于haskell - 内存IO功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9454255/

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