Ленивое чередование чистых вычислений, содержащихся внутри IO-монад - PullRequest
3 голосов
/ 15 февраля 2012

Есть ли какой-нибудь путь для интеллектуально ленивого чередования взаимозависимых чистых вычислений, возникающих после операций ввода-вывода?Я читаю два конфигурационных файла, первый идентифицирует второй, но второй определяет интерпретацию первого.

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
     ...

Мне интересно, если бы я мог избежать написания этой дополнительной функции procStateConfig', сделавprocBaseConfig и procStateConfig взаимно рекурсивны в том смысле, что каждый из них выполняется до тех пор, пока ему не потребуется информация от другого.

В частности, я мог бы, возможно, заменить procStateConfig' на procBaseConfig f_state undefined, если проигнорирую все вещи, которые зависят отcfg_base, но это не так наивно.

Я думаю, это может сработать, если мне не понадобится элемент cfg_state записи * для второго BS.readFile, нов настоящее время это выглядит сложно.И я бы предпочел сложить оба BS.readFile звонка в proc.. звонки.

1 Ответ

3 голосов
/ 15 февраля 2012

В принципе, лень делает это возможным. Проблема здесь в том, что вам нужно выполнить ввод / вывод на основе первого результата readFile. Обычный 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 s, она компилируется.)

...