Creating instances of abstract data types that recursively contain each other

For two types of dates defined as follows:

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

How can I do foo, and barso that foowas Foo bar "foo"and baris Bar foo "bar"?

How about when we change the types to:

data Foo = Foo Bar (MVar String)
data Bar = Bar Foo (MVar String)
+5
source share
3 answers

Just using is letenough ( letHaskell has letrecand supports mutually recursive definitions). In mutually recursive definitions, heap loops are set that look like this:

foo bar let rec

MVar - .

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 ()
+7

, , :

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

MVars , .

:

1.) , , C:

mutation = do
   -- setting up an empty mvar
   bar <- newEmptyMVar
   foo <- newMVar (Foo bar "foo")
   -- and then filling it in
   putMVar bar (Bar foo "foo")
   return (foo, bar)

2.) DoRec ( RecursiveDo) mfix :

{-# LANGUAGE DoRec #-} 

mutual = do
   rec foo <- newMVar (Foo bar "foo")
       bar <- newMVar (Bar foo "foo")
   return (foo, bar)

- :

mutual = do
   (foo, bar) <- mfix $ \(foo, bar) -> do
       foo <- newMVar (Foo bar "foo")
       bar <- newMVar (Bar foo "foo")
       return (foo, bar)
  return (foo, bar)
+5

The following works great thanks to the laziness of Haskells.

data Foo = Foo Bar String deriving Show
data Bar = Bar Foo String deriving Show

test = let
  foo = Foo bar "foo"
  bar = Bar foo "bar"
  in foo
0
source

All Articles