2

Trying to understand how these parameterized types work in Haskell, such as these:

data List a = Nil | Cons a (List a)
data Either a b = Left a | Right b
data Tree a = Nil | Node a (Tree a) (Tree a)
data Tree = Branch [Tree]
data Tree a = Node a [Tree a]

To make it a little more complicated I wanted to see what the definition looks like for a bipartite graph, basically a graph with two sets of nodes where the nodes only connect to nodes of the other set.

So.. (in JavaScript).... An example of how the data would be connected is like this:

var typeA_node1 = { id: 'a1' }
var typeA_node2 = { id: 'a2' }
var typeA_node3 = { id: 'a3' }

var typeB_node1 = { id: 'b1' }
var typeB_node2 = { id: 'b2' }
var typeB_node3 = { id: 'b3' }

typeA_node1.right = typeB_node3
typeB_node3.right = typeA_node2

typeA_node2.right = typeB_node2
typeB_node2.right = typeA_node3

typeA_node3.right = typeB_node1

Basically, a--b--a--b--a--b--a--b, a is always connected to b only, never to a. An a can be connected to many b nodes, I just didn't show that in the example.

Wondering how to define this properly using data or type in Haskell (or something else).

Lance Pollard
  • 66,757
  • 77
  • 237
  • 416

1 Answers1

2

I would use Data.Set for constructing both sets of vertices and another one for the edges. Now wrap them in a module where you hide them.

module BiPartiteGraph (create) where


import qualified Data.Set as Set 


data BiPartiteGraph a = BiPartiteGraph (Set.Set a) (Set.Set a) (Set.Set (a, a)) -- (U, V, E)


-- Construct a BiPartiteGraph from a list of edges
create :: Ord a => [(a, a)] -> BiPartiteGraph a
create _ = undefined


-- Implementation of the show function 
instance (Show a) => Show (BiPartiteGraph a) where
    show _ = undefined 
Elmex80s
  • 3,258
  • 1
  • 13
  • 22
  • 3
    This is nice for being close to the mathematical definition, but it has pretty unfortunate computational characteristics. For example, getting the edges associated with a given node must traverse all edges. I would consider instead using an adjacency map like `Map a (Set a)` (keys are nodes, values are the set of nodes on the other side they're connected to). You can either use one for each part or combine them, depending on your goals. ...OR just directly reuse `fgl` and maintain the bipartite invariant yourself. – Daniel Wagner Feb 18 '19 at 18:19
  • 1
    There are a lot of applications of bipartite graphs where one would want `data BiPartiteGraph a b = ...` or even `data BiPartiteGraph e a b = ...` – Jeremy List Feb 21 '19 at 02:44