Suppose someone makes a program to play chess, or solve sudoku. In this kind of program it makes sense to have a tree structure representing game states.
This tree would be very large, "practically infinite". Which isn't by itself a problem as Haskell supports infinite data structures.
An familiar example of an infinite data structure:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Nodes are only allocated when first used, so the list takes finite memory. One may also iterate over an infinite list if they don't keep references to its head, allowing the garbage collector to collect its parts which are not needed anymore.
Back to the tree example - suppose one does some iteration over the tree, the tree nodes iterated over may not be freed if the root of the tree is still needed (for example in an iterative deepening search, the tree would be iterated over several times and so the root needs to be kept).
One possible solution for this problem that I thought of is using an "unmemo-monad".
I'll try to demonstrate what this monad is supposed to do using monadic lists:
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))
Using nums :: [Int]
, the program would take a lot of memory as a reference to nums
is needed by lengthL nums
while it is being iterated over foldlL (+) 0 nums
.
The purpose of Unmemo
is to make the runtime not keep the nodes iterated over.
I attempted using ((->) ())
as Unmemo
, but it yields the same results as nums :: [Int]
does - the program uses a lot of memory, as evident by running it with +RTS -s
.
Is there anyway to implement Unmemo
that does what I want?
foldlL
orlengthL
, then there's no space leak. That makes me think that the problem is that GHC isn't collecting the space. What do you believe causes the leak? – yairchu