Можно ли сохранить операционную или бесплатную монаду haskell на диск?

У меня есть несколько простых примитивных операций, например:

В случае монады operational:

import Control.Monad.Operational
type Process a = Program ProcessI a
data ProcessI a where
    GetInput :: ProcessI String
    Dump :: String -> ProcessI ()
getInput :: Process String
getInput = singleton GetInput
dump :: String -> Process ()
dump = singleton . Dump

Или в случае free монады:

import Control.Monad.Free
type Process = Free ProcessF
data ProcessF a
    = GetInput (String -> a)
    | Dump String a
    deriving (Functor)
getInput :: Process String
getInput = liftF $ GetInput id
dump :: String -> Process ()
dump s = liftF $ Dump s ()

Простое действие одинаково в обоих случаях, например:

proc1 :: Process ()
proc1 = forever $ do
    a <- getInput
    b <- getInput
    dump $ a ++ b
    dump $ b ++ a

Мой вопрос: можно ли интерпретировать процесс (proc1) таким образом, чтобы продолжение на определенном этапе сериализовалось на диск, а затем восстанавливалось во время следующего выполнения программы? Не могли бы вы привести пример?

Если это невозможно, какой будет ближайший обходной путь?

Я хотел бы запустить программу только тогда, когда доступен следующий ввод, применить продолжение ввода, затем интерпретировать до следующего «getInput» и выйти.

Я мог бы представить себе сценарий, в котором все входные данные регистрируются, а затем воспроизводятся, чтобы привести систему в то же состояние, прежде чем продолжить, но в этом случае журнал будет расти без ограничений. Я не смог найти никакого способа отредактировать журнал в интерпретаторе, так как нет возможности сравнивать продолжения (нет экземпляра EQ) и процесс бесконечен.


person Zoran Bošnjak    schedule 01.09.2016    source источник
comment
Я не думаю, что это так (хотя возможно, что некоторые специальные GHC для распределенных вычислений могут это сделать, я никогда не копался в этом). Лучший стандартный подход, вероятно, состоит в том, чтобы обменять удобство и универсальность класса Monad Haskell на вашу собственную версию, которая представляет функции на каком-то абстрактном языке, который вы можете интерпретировать.   -  person dfeuer    schedule 01.09.2016


Ответы (1)


Как я понимаю, есть две проблемы:

  • продолжения могут содержать произвольные типы данных

  • продолжения могут содержать функции (т.е. замыкания)

Учитывая второе ограничение, вероятно, не существует простого способа сделать точно то, что вы хотите.

Обсуждение Можно ли сериализовать функции Haskell? указывает на библиотеку с именем packman. Из Ридми:

... эту функциональность можно использовать для оптимизации программ путем запоминания (при разных запусках программы) и для проверки выполнения программы в выбранных местах. Оба варианта использования показаны в наборе слайдов, ссылка на который приведена выше.

(Кажется, слайды упоминаются.)

Ограничение этого подхода заключается в том, что не все типы данных могут (или должны!) быть сериализованы, особенно изменяемые типы, такие как IORef, MVar и типы, связанные с STM, и иногда они заканчиваются переходами и замыканиями. что приводит к исключениям во время выполнения.

Кроме того, библиотека полагается на сериализованное продолжение, используемое тот же двоичный файл, который его создал, что может быть или не быть реальной проблемой для вашего приложения.

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

person Tikhon Jelvis    schedule 01.09.2016