懒惰地交错纯计算,这些计算包含在IO单子中。

3

在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',但这并不是那么简单。

我想象如果我不需要记录cfg_statecfg_base_fn元素进行第二个BS.readFile,那么这可能会起作用,但目前看起来很困难。而且我更愿意将两个BS.readFile调用合并到proc..调用中。

1个回答

3

原则上,懒惰使其成为可能。问题在于您需要根据第一个readFile的结果进行I/O操作。普通的Haskell不允许在do块中递归绑定,但是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
        }
  ; ...
  }

应该这样做。(至少,填写一些虚拟的undefined,它就可以编译。)


如果你想的话,可以通过重新构造使用mfix来避免DoRec - singpolyma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接