Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 873
MaiaVictor Avatar asked Oct 16 '15 00:10

MaiaVictor


1 Answers

{-# 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
like image 175
leftaroundabout Avatar answered Oct 02 '22 13:10

leftaroundabout