haskell / fgl

A Functional Graph Library for Haskell
http://hackage.haskell.org/package/fgl
Other
184 stars 54 forks source link

`gfiltermap` can result in inconsistent graph. #93

Open kindaro opened 4 years ago

kindaro commented 4 years ago

Consider this code:

isLeaf :: Context a b -> Bool
isLeaf (_, _, _, [ ]) = True
isLeaf (_, _, _, _  ) = False

tearLeaves = let p x = if isLeaf x then Nothing else Just x in gfiltermap p

Example:

λ dag3           
mkGraph [(1,'a'),(2,'b'),(3,'c')] [(1,3,())]
λ tearLeaves dag3
mkGraph [(1,'a')] [(1,3,())]

As you see, we obtain a hanging edge.

I propose gfiltermap is improved so that validity of graphs is preserved.

kindaro commented 4 years ago

Another example is gmap. Its behaviour depends on the order of traversal and does not make sense overall. For example, the last context to be traversed would always appear to be a leaf.

This can be remedied by making GDecomp an instance of comonad. gmap can then be defined in terms of extend on non-empty graphs, and the definition for an empty graph is trivial to add. I rolled it out at home and it seems to work.

So, in principle it is not a problem to define reasonable maps, therefore I think it is fair to say that we have a bug. I should like to contribute some code to remedy this situation if the maintainers are willing to review and merge.