Search code examples
data-structureshaskellrecursionabstract-data-type

Creating instances of Abstract Data Types that recursively contain each other


Given two date types defined as follows:

data Foo = Foo Bar String
data Bar = Bar Foo String

How can I make foo and bar such that foo is Foo bar "foo" and bar is Bar foo "bar"?

What about when we change the types to:

data Foo = Foo Bar (MVar String)
data Bar = Bar Foo (MVar String)

Solution

  • Just using a let is enough (let in Haskell is letrec, and supports mutually recursive definitions). The mutually recursive definitions set up cycles in the heap, that look like this:

    foo bar let rec

    The MVar initialization doesn't really change things in any meaningful way.

    import Control.Concurrent
    
    data Foo = Foo Bar (MVar String)
    
    data Bar = Bar Foo (MVar String)
    
    main = do
        a <- newMVar "foo"
        b <- newMVar "bar"
    
        let foo = Foo bar a
            bar = Bar foo b
    
        return ()