haskell - 惰性交错包含在 IO monad 内的纯计算

标签 haskell lazy-evaluation

是否有某种途径可以智能地延迟交错 IO 操作后出现的相互依赖的纯计算?我正在读取两个配置文件,第一个标识第二个配置文件,但第二个确定第一个配置文件的解释。

import qualified Data.ByteString.Char8 as BS
main = do
     ...
     f_state <- BS.readFile fn_state 
     let cfg_state' = procStateConfig' f_state
     f_base <- BS.readFile $ cfg_base_fn cfg_state'
     let cfg_base = procBaseConfig f_base
     let cfg_state = procStateConfig f_state cfg_base
     ...

我很好奇是否可以通过使 procBaseConfigprocStateConfig 相互递归来避免编写这个额外的函数 procStateConfig',因为每个函数都执行直到它需要对方提供信息。

特别是,如果我忽略所有依赖于 cfg_base 的内容,我也许可以用 procBaseConfig f_state undefined 替换 procStateConfig',但是这个工作起来并不那么天真。

我想如果我不需要第二个 BS.readFile 记录 cfg_statecfg_base_fn 元素,这可能会起作用,但是目前看来很难。而且我宁愿将两个 BS.readFile 调用折叠到 proc.. cals 中。

最佳答案

原则上,懒惰使得这成为可能。这里的问题是您需要根据第一个 readFile 的结果执行 I/O。普通 Haskell 不允许在 do block 中进行递归绑定(bind),但 GHC 扩展 DoRec 允许。我从来没有使用过它,所以我可能会犯一些错误,但是

{-# LANGUAGE DoRec #-}
module Main where

import qualified Data.ByteString.Char8 as BS

main = do
    ...
  { f_state <- BS.readFile fn_state
  ; rec { let cfg_state = procStateConfig f_state cfg_base
        ; cfg_base <- fmap procBaseConfig $ BS.readFile $ cfg_base_fn cfg_state
        }
  ; ...
  }

应该这样做。 (至少,填充一些虚拟的未定义,它可以编译。)

关于haskell - 惰性交错包含在 IO monad 内的纯计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9285596/

相关文章:

julia - 没有更好的方法来组合多个 `Union{T, Nothing}`

haskell - haskell中seq和$有什么区别?

haskell - GHC编译进度信息

haskell - 列出 Haskell 中的惰性求值

haskell - 如何定义严格的存在类型?

haskell - 惰性状态转换器在 2D 递归中急切地消耗惰性列表

haskell - 使用 foldr 的功能太急切了

algorithm - 惰性求值和时间复杂度

haskell - 酸性状态查询的意外返回类型(Happstack)

Haskell 函数定义未按预期工作