ohnosequences / monochord

An exploration of string diagrams, monoidal categories and functional programming in the browser
GNU Affero General Public License v3.0
0 stars 1 forks source link

Defining (monoidal) graphs in Elm #5

Open mroman42 opened 8 years ago

mroman42 commented 8 years ago

We need to define simple graphs, monoidal graphs (where we substitute the set of vertices for the free monoid over those vertices) and operations on them in Elm.

mroman42 commented 8 years ago

First ideas:

module Graph
    ( Graph
    , emptyGraph
    , addNodes
    , addEdges
    , neighbors
    , adjacent
    ) where

import Dict exposing (..)
import List

-- Graph as a dictionary
type alias Label   = String
type alias Edge  a = (a,a,Label)
type alias Graph a = Dict a (Dict a Label)

emptyGraph : Graph comparable
emptyGraph = empty

adjacent : Graph comparable -> comparable -> comparable -> Bool
adjacent g x y = case (get x g) of 
                    Just adj -> member y adj
                    Nothing  -> False 

neighbors : Graph comparable -> comparable -> List comparable
neighbors g x = case (get x g) of
                    Just adj -> keys adj
                    Nothing  -> []

addNode : comparable -> Graph comparable -> Graph comparable
addNode x = insert x empty

addNodes : Graph comparable -> List comparable -> Graph comparable
addNodes = List.foldr addNode

addEdge : Edge comparable -> Graph comparable -> Graph comparable 
addEdge (x,y,l) = let adds md = case md of
                                      Just d  -> Just (insert y l d) 
                                      Nothing -> Nothing
                  in  update x adds

addEdges :  Graph comparable -> List (Edge comparable) -> Graph comparable 
addEdges = List.foldr addEdge

-- Test
testgraph = addEdges (addNodes emptyGraph [1,2,3,4]) [(1,2,"a"),(2,3,"b"),(1,3,"c")]
mroman42 commented 8 years ago

I have found a problem trying to use dictionaries in Elm. A Dict needs the type of its keys to be comparable, and only a few primitive types are comparable. Because of that, it is not possible to use the core containers (Set, Dict) with user-defined data types. This is an open issue yet:

In particular, that implies that the type of our nodes couldn't be arbitrary. And that would be needed in order to define monoidal graphs, where the nodes should have the structure of a free monoid.

laughedelic commented 8 years ago

Hi @M42! It's great that you are back on track :+1: Unfortunately, we're super-busy this week with some urgent project. I'll hopefully take a look at what you're proposing closer to the end of week.

Also, I think it will be better if you will maintain your experiments code in the repo itself (in a separate branch + pull-request). Create an elm project with managed deps and the code + examples. Then it will be easier to try it and discuss.

eparejatobes commented 8 years ago

@M42 my impression when I skimmed through the Elm std lib was that we will need to build everything from scratch :) I would do everything in terms of extensible records. This is bound to be more verbose, but it has the advantage of being free from the inheritance-like structure of typeclasses.

eparejatobes commented 8 years ago

About monoidal graphs as a presheaf category: take as objects $V, E_{i,j}$ with maps ${s_1, ... , si} : E{i,j} \to V$ and ${t_1, ... , tj} : E{i, j} \to V$. Or the opposite of that, whatever.

Then for a presheaf $G$, $G{i,j} = G(E{i,j})$ is the set of monoidal edges with $i$ inputs and $j$ outputs.

mroman42 commented 8 years ago

Ok! I am writing the experimental definitions in the graphs branch.