Любой способ создать unmemo-монаду?

Предположим, кто-то создает программу для игры в шахматы или решения судоку. В программах такого рода имеет смысл иметь древовидную структуру, представляющую игровые состояния.

Это дерево будет очень большим, «практически бесконечным». Само по себе это не проблема, поскольку Haskell поддерживает бесконечные структуры данных.

Знакомый пример бесконечной структуры данных:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

Узлы выделяются только при первом использовании, поэтому список занимает ограниченную память. Можно также перебирать бесконечный список, если они не хранят ссылки на его заголовок, что позволяет сборщику мусора собирать его части, которые больше не нужны.

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

Одно из возможных решений этой проблемы.

Я попытаюсь продемонстрировать, что эта монада должна делать, используя монадические списки:

import Control.Monad.ListT (ListT)  -- cabal install List
import Data.Copointed  -- cabal install pointed
import Data.List.Class
import Prelude hiding (enumFromTo)

nums :: ListT Unmemo Int  -- What is Unmemo?
nums = enumFromTo 0 1000000

main = print $ div (copoint (foldlL (+) 0 nums)) (copoint (lengthL nums))

Используя nums :: [Int] , программу потребует много памяти, поскольку ссылка на nums необходима для lengthL nums , пока она выполняется по foldlL (+) 0 nums .

Цель Unmemo - заставить среду выполнения не сохранять повторяющиеся узлы.

Я попытался использовать ((->) ()) как Unmemo , но дает те же результаты, что и nums :: [Int] - программа использует много памяти, что очевидно, если запустить ее с помощью + RTS -s .

Есть ли способ реализовать Unmemo , который делает то, что я хочу?

10
задан yairchu 2 June 2011 в 21:28
поделиться