haskellgraphsyntaxtying-the-knot

Is there any way to convenient way to express graphs using the tying-the-knot strategy?


As explained on my previous question, it is impossible to differ two graphs made using the tying the knot strategy if you don't have some kind of unique label on your nodes. Using a two-edged graph as an example:

data Node = Node Int Node Node

square = a where
    a = Node 0 b c
    b = Node 1 a d
    c = Node 2 a d
    d = Node 3 b c

Writing square that way is a little inconvenient and error-prone due to the need of manually writing labels. That kind of pattern would usually call for a monad:

square = do
    a <- Node b c
    b <- Node a d
    c <- Node a d
    d <- Node b c
    return a

But this also can't be done since monads are sequential. Is there any convenient way to write tying-the-knot graphs?


Solution

  • {-# LANGUAGE RecursiveDo #-}
    
    import Control.Monad.State
    
    type Intividual a = State Int a
    
    data Node = Node Int Node Node
    
    newNode :: Node -> Node -> Intividual Node
    newNode a b = state $ \i -> (Node i a b, succ i)
    
    square :: Node
    square = (`evalState`0) $ mdo
       a <- newNode b c
       b <- newNode a d
       c <- newNode a d
       d <- newNode b c
       return a