diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,4 @@
+* 0.1.0.0 (20/12/2012)
+
+  Release candidate
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Marco Zocca (c) 2020
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Marco Zocca nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# algebraic-graphs-io
+
+[![Build Status](https://travis-ci.org/ocramz/algebraic-graphs-io.png)](https://travis-ci.org/ocramz/algebraic-graphs-io)
+
+TODO Description.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/algebraic-graphs-io.cabal b/algebraic-graphs-io.cabal
new file mode 100644
--- /dev/null
+++ b/algebraic-graphs-io.cabal
@@ -0,0 +1,48 @@
+name:                algebraic-graphs-io
+version:             0.1.1.0
+synopsis:            I/O utilities for algebraic-graphs
+description:         I/O utilities for algebraic-graphs. Currently, parsers for the GML format.
+homepage:            https://github.com/ocramz/algebraic-graphs-io
+license:             BSD3
+license-file:        LICENSE
+author:              Marco Zocca
+maintainer:          ocramz
+copyright:           2020-2021 ocramz
+category:            Graphs, Parsing
+build-type:          Simple
+extra-source-files:  README.md
+                     CHANGELOG.md
+                     assets/basic.gml
+                     assets/labeled.gml
+                     assets/karate.gml
+                     assets/lesmiserables.gml
+cabal-version:       >=1.10
+tested-with:         GHC == 8.8.4
+
+library
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+  hs-source-dirs:      src
+  exposed-modules:     Algebra.Graph.IO.GML
+                       Algebra.Graph.IO.Internal.Megaparsec
+  build-depends:       base >= 4.7 && < 5
+                     , algebraic-graphs
+                     , containers
+                     , megaparsec
+                     , parser-combinators
+                     , text
+
+test-suite spec
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , algebraic-graphs-io
+                     , hspec
+                     , QuickCheck
+
+source-repository head
+  type:     git
+  location: https://github.com/ocramz/algebraic-graphs-io
diff --git a/assets/basic.gml b/assets/basic.gml
new file mode 100644
--- /dev/null
+++ b/assets/basic.gml
@@ -0,0 +1,25 @@
+graph
+[
+  node
+  [
+   id A
+  ]
+  node
+  [
+   id B
+  ]
+  node
+  [
+   id C
+  ]
+   edge
+  [
+   source B
+   target A
+  ]
+  edge
+  [
+   source C
+   target A
+  ]
+]
diff --git a/assets/karate.gml b/assets/karate.gml
new file mode 100644
--- /dev/null
+++ b/assets/karate.gml
@@ -0,0 +1,530 @@
+Creator "Mark Newman on Fri Jul 21 12:39:27 2006"
+graph
+[
+  node
+  [
+    id 1
+  ]
+  node
+  [
+    id 2
+  ]
+  node
+  [
+    id 3
+  ]
+  node
+  [
+    id 4
+  ]
+  node
+  [
+    id 5
+  ]
+  node
+  [
+    id 6
+  ]
+  node
+  [
+    id 7
+  ]
+  node
+  [
+    id 8
+  ]
+  node
+  [
+    id 9
+  ]
+  node
+  [
+    id 10
+  ]
+  node
+  [
+    id 11
+  ]
+  node
+  [
+    id 12
+  ]
+  node
+  [
+    id 13
+  ]
+  node
+  [
+    id 14
+  ]
+  node
+  [
+    id 15
+  ]
+  node
+  [
+    id 16
+  ]
+  node
+  [
+    id 17
+  ]
+  node
+  [
+    id 18
+  ]
+  node
+  [
+    id 19
+  ]
+  node
+  [
+    id 20
+  ]
+  node
+  [
+    id 21
+  ]
+  node
+  [
+    id 22
+  ]
+  node
+  [
+    id 23
+  ]
+  node
+  [
+    id 24
+  ]
+  node
+  [
+    id 25
+  ]
+  node
+  [
+    id 26
+  ]
+  node
+  [
+    id 27
+  ]
+  node
+  [
+    id 28
+  ]
+  node
+  [
+    id 29
+  ]
+  node
+  [
+    id 30
+  ]
+  node
+  [
+    id 31
+  ]
+  node
+  [
+    id 32
+  ]
+  node
+  [
+    id 33
+  ]
+  node
+  [
+    id 34
+  ]
+  edge
+  [
+    source 2
+    target 1
+  ]
+  edge
+  [
+    source 3
+    target 1
+  ]
+  edge
+  [
+    source 3
+    target 2
+  ]
+  edge
+  [
+    source 4
+    target 1
+  ]
+  edge
+  [
+    source 4
+    target 2
+  ]
+  edge
+  [
+    source 4
+    target 3
+  ]
+  edge
+  [
+    source 5
+    target 1
+  ]
+  edge
+  [
+    source 6
+    target 1
+  ]
+  edge
+  [
+    source 7
+    target 1
+  ]
+  edge
+  [
+    source 7
+    target 5
+  ]
+  edge
+  [
+    source 7
+    target 6
+  ]
+  edge
+  [
+    source 8
+    target 1
+  ]
+  edge
+  [
+    source 8
+    target 2
+  ]
+  edge
+  [
+    source 8
+    target 3
+  ]
+  edge
+  [
+    source 8
+    target 4
+  ]
+  edge
+  [
+    source 9
+    target 1
+  ]
+  edge
+  [
+    source 9
+    target 3
+  ]
+  edge
+  [
+    source 10
+    target 3
+  ]
+  edge
+  [
+    source 11
+    target 1
+  ]
+  edge
+  [
+    source 11
+    target 5
+  ]
+  edge
+  [
+    source 11
+    target 6
+  ]
+  edge
+  [
+    source 12
+    target 1
+  ]
+  edge
+  [
+    source 13
+    target 1
+  ]
+  edge
+  [
+    source 13
+    target 4
+  ]
+  edge
+  [
+    source 14
+    target 1
+  ]
+  edge
+  [
+    source 14
+    target 2
+  ]
+  edge
+  [
+    source 14
+    target 3
+  ]
+  edge
+  [
+    source 14
+    target 4
+  ]
+  edge
+  [
+    source 17
+    target 6
+  ]
+  edge
+  [
+    source 17
+    target 7
+  ]
+  edge
+  [
+    source 18
+    target 1
+  ]
+  edge
+  [
+    source 18
+    target 2
+  ]
+  edge
+  [
+    source 20
+    target 1
+  ]
+  edge
+  [
+    source 20
+    target 2
+  ]
+  edge
+  [
+    source 22
+    target 1
+  ]
+  edge
+  [
+    source 22
+    target 2
+  ]
+  edge
+  [
+    source 26
+    target 24
+  ]
+  edge
+  [
+    source 26
+    target 25
+  ]
+  edge
+  [
+    source 28
+    target 3
+  ]
+  edge
+  [
+    source 28
+    target 24
+  ]
+  edge
+  [
+    source 28
+    target 25
+  ]
+  edge
+  [
+    source 29
+    target 3
+  ]
+  edge
+  [
+    source 30
+    target 24
+  ]
+  edge
+  [
+    source 30
+    target 27
+  ]
+  edge
+  [
+    source 31
+    target 2
+  ]
+  edge
+  [
+    source 31
+    target 9
+  ]
+  edge
+  [
+    source 32
+    target 1
+  ]
+  edge
+  [
+    source 32
+    target 25
+  ]
+  edge
+  [
+    source 32
+    target 26
+  ]
+  edge
+  [
+    source 32
+    target 29
+  ]
+  edge
+  [
+    source 33
+    target 3
+  ]
+  edge
+  [
+    source 33
+    target 9
+  ]
+  edge
+  [
+    source 33
+    target 15
+  ]
+  edge
+  [
+    source 33
+    target 16
+  ]
+  edge
+  [
+    source 33
+    target 19
+  ]
+  edge
+  [
+    source 33
+    target 21
+  ]
+  edge
+  [
+    source 33
+    target 23
+  ]
+  edge
+  [
+    source 33
+    target 24
+  ]
+  edge
+  [
+    source 33
+    target 30
+  ]
+  edge
+  [
+    source 33
+    target 31
+  ]
+  edge
+  [
+    source 33
+    target 32
+  ]
+  edge
+  [
+    source 34
+    target 9
+  ]
+  edge
+  [
+    source 34
+    target 10
+  ]
+  edge
+  [
+    source 34
+    target 14
+  ]
+  edge
+  [
+    source 34
+    target 15
+  ]
+  edge
+  [
+    source 34
+    target 16
+  ]
+  edge
+  [
+    source 34
+    target 19
+  ]
+  edge
+  [
+    source 34
+    target 20
+  ]
+  edge
+  [
+    source 34
+    target 21
+  ]
+  edge
+  [
+    source 34
+    target 23
+  ]
+  edge
+  [
+    source 34
+    target 24
+  ]
+  edge
+  [
+    source 34
+    target 27
+  ]
+  edge
+  [
+    source 34
+    target 28
+  ]
+  edge
+  [
+    source 34
+    target 29
+  ]
+  edge
+  [
+    source 34
+    target 30
+  ]
+  edge
+  [
+    source 34
+    target 31
+  ]
+  edge
+  [
+    source 34
+    target 32
+  ]
+  edge
+  [
+    source 34
+    target 33
+  ]
+]
diff --git a/assets/labeled.gml b/assets/labeled.gml
new file mode 100644
--- /dev/null
+++ b/assets/labeled.gml
@@ -0,0 +1,30 @@
+graph
+[
+  node
+  [
+   id A
+   label "Node A"
+  ]
+  node
+  [
+   id B
+   label "Node B"
+  ]
+  node
+  [
+   id C
+   label "Node C"
+  ]
+   edge
+  [
+   source B
+   target A
+   label "Edge B to A"
+  ]
+  edge
+  [
+   source C
+   target A
+   label "Edge C to A"
+  ]
+]
diff --git a/assets/lesmiserables.gml b/assets/lesmiserables.gml
new file mode 100644
--- /dev/null
+++ b/assets/lesmiserables.gml
@@ -0,0 +1,1913 @@
+Creator "Mark Newman on Fri Jul 21 12:44:53 2006"
+graph
+[
+  node
+  [
+    id 0
+    label "Myriel"
+  ]
+  node
+  [
+    id 1
+    label "Napoleon"
+  ]
+  node
+  [
+    id 2
+    label "MlleBaptistine"
+  ]
+  node
+  [
+    id 3
+    label "MmeMagloire"
+  ]
+  node
+  [
+    id 4
+    label "CountessDeLo"
+  ]
+  node
+  [
+    id 5
+    label "Geborand"
+  ]
+  node
+  [
+    id 6
+    label "Champtercier"
+  ]
+  node
+  [
+    id 7
+    label "Cravatte"
+  ]
+  node
+  [
+    id 8
+    label "Count"
+  ]
+  node
+  [
+    id 9
+    label "OldMan"
+  ]
+  node
+  [
+    id 10
+    label "Labarre"
+  ]
+  node
+  [
+    id 11
+    label "Valjean"
+  ]
+  node
+  [
+    id 12
+    label "Marguerite"
+  ]
+  node
+  [
+    id 13
+    label "MmeDeR"
+  ]
+  node
+  [
+    id 14
+    label "Isabeau"
+  ]
+  node
+  [
+    id 15
+    label "Gervais"
+  ]
+  node
+  [
+    id 16
+    label "Tholomyes"
+  ]
+  node
+  [
+    id 17
+    label "Listolier"
+  ]
+  node
+  [
+    id 18
+    label "Fameuil"
+  ]
+  node
+  [
+    id 19
+    label "Blacheville"
+  ]
+  node
+  [
+    id 20
+    label "Favourite"
+  ]
+  node
+  [
+    id 21
+    label "Dahlia"
+  ]
+  node
+  [
+    id 22
+    label "Zephine"
+  ]
+  node
+  [
+    id 23
+    label "Fantine"
+  ]
+  node
+  [
+    id 24
+    label "MmeThenardier"
+  ]
+  node
+  [
+    id 25
+    label "Thenardier"
+  ]
+  node
+  [
+    id 26
+    label "Cosette"
+  ]
+  node
+  [
+    id 27
+    label "Javert"
+  ]
+  node
+  [
+    id 28
+    label "Fauchelevent"
+  ]
+  node
+  [
+    id 29
+    label "Bamatabois"
+  ]
+  node
+  [
+    id 30
+    label "Perpetue"
+  ]
+  node
+  [
+    id 31
+    label "Simplice"
+  ]
+  node
+  [
+    id 32
+    label "Scaufflaire"
+  ]
+  node
+  [
+    id 33
+    label "Woman1"
+  ]
+  node
+  [
+    id 34
+    label "Judge"
+  ]
+  node
+  [
+    id 35
+    label "Champmathieu"
+  ]
+  node
+  [
+    id 36
+    label "Brevet"
+  ]
+  node
+  [
+    id 37
+    label "Chenildieu"
+  ]
+  node
+  [
+    id 38
+    label "Cochepaille"
+  ]
+  node
+  [
+    id 39
+    label "Pontmercy"
+  ]
+  node
+  [
+    id 40
+    label "Boulatruelle"
+  ]
+  node
+  [
+    id 41
+    label "Eponine"
+  ]
+  node
+  [
+    id 42
+    label "Anzelma"
+  ]
+  node
+  [
+    id 43
+    label "Woman2"
+  ]
+  node
+  [
+    id 44
+    label "MotherInnocent"
+  ]
+  node
+  [
+    id 45
+    label "Gribier"
+  ]
+  node
+  [
+    id 46
+    label "Jondrette"
+  ]
+  node
+  [
+    id 47
+    label "MmeBurgon"
+  ]
+  node
+  [
+    id 48
+    label "Gavroche"
+  ]
+  node
+  [
+    id 49
+    label "Gillenormand"
+  ]
+  node
+  [
+    id 50
+    label "Magnon"
+  ]
+  node
+  [
+    id 51
+    label "MlleGillenormand"
+  ]
+  node
+  [
+    id 52
+    label "MmePontmercy"
+  ]
+  node
+  [
+    id 53
+    label "MlleVaubois"
+  ]
+  node
+  [
+    id 54
+    label "LtGillenormand"
+  ]
+  node
+  [
+    id 55
+    label "Marius"
+  ]
+  node
+  [
+    id 56
+    label "BaronessT"
+  ]
+  node
+  [
+    id 57
+    label "Mabeuf"
+  ]
+  node
+  [
+    id 58
+    label "Enjolras"
+  ]
+  node
+  [
+    id 59
+    label "Combeferre"
+  ]
+  node
+  [
+    id 60
+    label "Prouvaire"
+  ]
+  node
+  [
+    id 61
+    label "Feuilly"
+  ]
+  node
+  [
+    id 62
+    label "Courfeyrac"
+  ]
+  node
+  [
+    id 63
+    label "Bahorel"
+  ]
+  node
+  [
+    id 64
+    label "Bossuet"
+  ]
+  node
+  [
+    id 65
+    label "Joly"
+  ]
+  node
+  [
+    id 66
+    label "Grantaire"
+  ]
+  node
+  [
+    id 67
+    label "MotherPlutarch"
+  ]
+  node
+  [
+    id 68
+    label "Gueulemer"
+  ]
+  node
+  [
+    id 69
+    label "Babet"
+  ]
+  node
+  [
+    id 70
+    label "Claquesous"
+  ]
+  node
+  [
+    id 71
+    label "Montparnasse"
+  ]
+  node
+  [
+    id 72
+    label "Toussaint"
+  ]
+  node
+  [
+    id 73
+    label "Child1"
+  ]
+  node
+  [
+    id 74
+    label "Child2"
+  ]
+  node
+  [
+    id 75
+    label "Brujon"
+  ]
+  node
+  [
+    id 76
+    label "MmeHucheloup"
+  ]
+  edge
+  [
+    source 1
+    target 0
+    value 1
+  ]
+  edge
+  [
+    source 2
+    target 0
+    value 8
+  ]
+  edge
+  [
+    source 3
+    target 0
+    value 10
+  ]
+  edge
+  [
+    source 3
+    target 2
+    value 6
+  ]
+  edge
+  [
+    source 4
+    target 0
+    value 1
+  ]
+  edge
+  [
+    source 5
+    target 0
+    value 1
+  ]
+  edge
+  [
+    source 6
+    target 0
+    value 1
+  ]
+  edge
+  [
+    source 7
+    target 0
+    value 1
+  ]
+  edge
+  [
+    source 8
+    target 0
+    value 2
+  ]
+  edge
+  [
+    source 9
+    target 0
+    value 1
+  ]
+  edge
+  [
+    source 11
+    target 10
+    value 1
+  ]
+  edge
+  [
+    source 11
+    target 3
+    value 3
+  ]
+  edge
+  [
+    source 11
+    target 2
+    value 3
+  ]
+  edge
+  [
+    source 11
+    target 0
+    value 5
+  ]
+  edge
+  [
+    source 12
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 13
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 14
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 15
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 17
+    target 16
+    value 4
+  ]
+  edge
+  [
+    source 18
+    target 16
+    value 4
+  ]
+  edge
+  [
+    source 18
+    target 17
+    value 4
+  ]
+  edge
+  [
+    source 19
+    target 16
+    value 4
+  ]
+  edge
+  [
+    source 19
+    target 17
+    value 4
+  ]
+  edge
+  [
+    source 19
+    target 18
+    value 4
+  ]
+  edge
+  [
+    source 20
+    target 16
+    value 3
+  ]
+  edge
+  [
+    source 20
+    target 17
+    value 3
+  ]
+  edge
+  [
+    source 20
+    target 18
+    value 3
+  ]
+  edge
+  [
+    source 20
+    target 19
+    value 4
+  ]
+  edge
+  [
+    source 21
+    target 16
+    value 3
+  ]
+  edge
+  [
+    source 21
+    target 17
+    value 3
+  ]
+  edge
+  [
+    source 21
+    target 18
+    value 3
+  ]
+  edge
+  [
+    source 21
+    target 19
+    value 3
+  ]
+  edge
+  [
+    source 21
+    target 20
+    value 5
+  ]
+  edge
+  [
+    source 22
+    target 16
+    value 3
+  ]
+  edge
+  [
+    source 22
+    target 17
+    value 3
+  ]
+  edge
+  [
+    source 22
+    target 18
+    value 3
+  ]
+  edge
+  [
+    source 22
+    target 19
+    value 3
+  ]
+  edge
+  [
+    source 22
+    target 20
+    value 4
+  ]
+  edge
+  [
+    source 22
+    target 21
+    value 4
+  ]
+  edge
+  [
+    source 23
+    target 16
+    value 3
+  ]
+  edge
+  [
+    source 23
+    target 17
+    value 3
+  ]
+  edge
+  [
+    source 23
+    target 18
+    value 3
+  ]
+  edge
+  [
+    source 23
+    target 19
+    value 3
+  ]
+  edge
+  [
+    source 23
+    target 20
+    value 4
+  ]
+  edge
+  [
+    source 23
+    target 21
+    value 4
+  ]
+  edge
+  [
+    source 23
+    target 22
+    value 4
+  ]
+  edge
+  [
+    source 23
+    target 12
+    value 2
+  ]
+  edge
+  [
+    source 23
+    target 11
+    value 9
+  ]
+  edge
+  [
+    source 24
+    target 23
+    value 2
+  ]
+  edge
+  [
+    source 24
+    target 11
+    value 7
+  ]
+  edge
+  [
+    source 25
+    target 24
+    value 13
+  ]
+  edge
+  [
+    source 25
+    target 23
+    value 1
+  ]
+  edge
+  [
+    source 25
+    target 11
+    value 12
+  ]
+  edge
+  [
+    source 26
+    target 24
+    value 4
+  ]
+  edge
+  [
+    source 26
+    target 11
+    value 31
+  ]
+  edge
+  [
+    source 26
+    target 16
+    value 1
+  ]
+  edge
+  [
+    source 26
+    target 25
+    value 1
+  ]
+  edge
+  [
+    source 27
+    target 11
+    value 17
+  ]
+  edge
+  [
+    source 27
+    target 23
+    value 5
+  ]
+  edge
+  [
+    source 27
+    target 25
+    value 5
+  ]
+  edge
+  [
+    source 27
+    target 24
+    value 1
+  ]
+  edge
+  [
+    source 27
+    target 26
+    value 1
+  ]
+  edge
+  [
+    source 28
+    target 11
+    value 8
+  ]
+  edge
+  [
+    source 28
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 29
+    target 23
+    value 1
+  ]
+  edge
+  [
+    source 29
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 29
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 30
+    target 23
+    value 1
+  ]
+  edge
+  [
+    source 31
+    target 30
+    value 2
+  ]
+  edge
+  [
+    source 31
+    target 11
+    value 3
+  ]
+  edge
+  [
+    source 31
+    target 23
+    value 2
+  ]
+  edge
+  [
+    source 31
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 32
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 33
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 33
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 34
+    target 11
+    value 3
+  ]
+  edge
+  [
+    source 34
+    target 29
+    value 2
+  ]
+  edge
+  [
+    source 35
+    target 11
+    value 3
+  ]
+  edge
+  [
+    source 35
+    target 34
+    value 3
+  ]
+  edge
+  [
+    source 35
+    target 29
+    value 2
+  ]
+  edge
+  [
+    source 36
+    target 34
+    value 2
+  ]
+  edge
+  [
+    source 36
+    target 35
+    value 2
+  ]
+  edge
+  [
+    source 36
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 36
+    target 29
+    value 1
+  ]
+  edge
+  [
+    source 37
+    target 34
+    value 2
+  ]
+  edge
+  [
+    source 37
+    target 35
+    value 2
+  ]
+  edge
+  [
+    source 37
+    target 36
+    value 2
+  ]
+  edge
+  [
+    source 37
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 37
+    target 29
+    value 1
+  ]
+  edge
+  [
+    source 38
+    target 34
+    value 2
+  ]
+  edge
+  [
+    source 38
+    target 35
+    value 2
+  ]
+  edge
+  [
+    source 38
+    target 36
+    value 2
+  ]
+  edge
+  [
+    source 38
+    target 37
+    value 2
+  ]
+  edge
+  [
+    source 38
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 38
+    target 29
+    value 1
+  ]
+  edge
+  [
+    source 39
+    target 25
+    value 1
+  ]
+  edge
+  [
+    source 40
+    target 25
+    value 1
+  ]
+  edge
+  [
+    source 41
+    target 24
+    value 2
+  ]
+  edge
+  [
+    source 41
+    target 25
+    value 3
+  ]
+  edge
+  [
+    source 42
+    target 41
+    value 2
+  ]
+  edge
+  [
+    source 42
+    target 25
+    value 2
+  ]
+  edge
+  [
+    source 42
+    target 24
+    value 1
+  ]
+  edge
+  [
+    source 43
+    target 11
+    value 3
+  ]
+  edge
+  [
+    source 43
+    target 26
+    value 1
+  ]
+  edge
+  [
+    source 43
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 44
+    target 28
+    value 3
+  ]
+  edge
+  [
+    source 44
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 45
+    target 28
+    value 2
+  ]
+  edge
+  [
+    source 47
+    target 46
+    value 1
+  ]
+  edge
+  [
+    source 48
+    target 47
+    value 2
+  ]
+  edge
+  [
+    source 48
+    target 25
+    value 1
+  ]
+  edge
+  [
+    source 48
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 48
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 49
+    target 26
+    value 3
+  ]
+  edge
+  [
+    source 49
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 50
+    target 49
+    value 1
+  ]
+  edge
+  [
+    source 50
+    target 24
+    value 1
+  ]
+  edge
+  [
+    source 51
+    target 49
+    value 9
+  ]
+  edge
+  [
+    source 51
+    target 26
+    value 2
+  ]
+  edge
+  [
+    source 51
+    target 11
+    value 2
+  ]
+  edge
+  [
+    source 52
+    target 51
+    value 1
+  ]
+  edge
+  [
+    source 52
+    target 39
+    value 1
+  ]
+  edge
+  [
+    source 53
+    target 51
+    value 1
+  ]
+  edge
+  [
+    source 54
+    target 51
+    value 2
+  ]
+  edge
+  [
+    source 54
+    target 49
+    value 1
+  ]
+  edge
+  [
+    source 54
+    target 26
+    value 1
+  ]
+  edge
+  [
+    source 55
+    target 51
+    value 6
+  ]
+  edge
+  [
+    source 55
+    target 49
+    value 12
+  ]
+  edge
+  [
+    source 55
+    target 39
+    value 1
+  ]
+  edge
+  [
+    source 55
+    target 54
+    value 1
+  ]
+  edge
+  [
+    source 55
+    target 26
+    value 21
+  ]
+  edge
+  [
+    source 55
+    target 11
+    value 19
+  ]
+  edge
+  [
+    source 55
+    target 16
+    value 1
+  ]
+  edge
+  [
+    source 55
+    target 25
+    value 2
+  ]
+  edge
+  [
+    source 55
+    target 41
+    value 5
+  ]
+  edge
+  [
+    source 55
+    target 48
+    value 4
+  ]
+  edge
+  [
+    source 56
+    target 49
+    value 1
+  ]
+  edge
+  [
+    source 56
+    target 55
+    value 1
+  ]
+  edge
+  [
+    source 57
+    target 55
+    value 1
+  ]
+  edge
+  [
+    source 57
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 57
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 58
+    target 55
+    value 7
+  ]
+  edge
+  [
+    source 58
+    target 48
+    value 7
+  ]
+  edge
+  [
+    source 58
+    target 27
+    value 6
+  ]
+  edge
+  [
+    source 58
+    target 57
+    value 1
+  ]
+  edge
+  [
+    source 58
+    target 11
+    value 4
+  ]
+  edge
+  [
+    source 59
+    target 58
+    value 15
+  ]
+  edge
+  [
+    source 59
+    target 55
+    value 5
+  ]
+  edge
+  [
+    source 59
+    target 48
+    value 6
+  ]
+  edge
+  [
+    source 59
+    target 57
+    value 2
+  ]
+  edge
+  [
+    source 60
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 60
+    target 58
+    value 4
+  ]
+  edge
+  [
+    source 60
+    target 59
+    value 2
+  ]
+  edge
+  [
+    source 61
+    target 48
+    value 2
+  ]
+  edge
+  [
+    source 61
+    target 58
+    value 6
+  ]
+  edge
+  [
+    source 61
+    target 60
+    value 2
+  ]
+  edge
+  [
+    source 61
+    target 59
+    value 5
+  ]
+  edge
+  [
+    source 61
+    target 57
+    value 1
+  ]
+  edge
+  [
+    source 61
+    target 55
+    value 1
+  ]
+  edge
+  [
+    source 62
+    target 55
+    value 9
+  ]
+  edge
+  [
+    source 62
+    target 58
+    value 17
+  ]
+  edge
+  [
+    source 62
+    target 59
+    value 13
+  ]
+  edge
+  [
+    source 62
+    target 48
+    value 7
+  ]
+  edge
+  [
+    source 62
+    target 57
+    value 2
+  ]
+  edge
+  [
+    source 62
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 62
+    target 61
+    value 6
+  ]
+  edge
+  [
+    source 62
+    target 60
+    value 3
+  ]
+  edge
+  [
+    source 63
+    target 59
+    value 5
+  ]
+  edge
+  [
+    source 63
+    target 48
+    value 5
+  ]
+  edge
+  [
+    source 63
+    target 62
+    value 6
+  ]
+  edge
+  [
+    source 63
+    target 57
+    value 2
+  ]
+  edge
+  [
+    source 63
+    target 58
+    value 4
+  ]
+  edge
+  [
+    source 63
+    target 61
+    value 3
+  ]
+  edge
+  [
+    source 63
+    target 60
+    value 2
+  ]
+  edge
+  [
+    source 63
+    target 55
+    value 1
+  ]
+  edge
+  [
+    source 64
+    target 55
+    value 5
+  ]
+  edge
+  [
+    source 64
+    target 62
+    value 12
+  ]
+  edge
+  [
+    source 64
+    target 48
+    value 5
+  ]
+  edge
+  [
+    source 64
+    target 63
+    value 4
+  ]
+  edge
+  [
+    source 64
+    target 58
+    value 10
+  ]
+  edge
+  [
+    source 64
+    target 61
+    value 6
+  ]
+  edge
+  [
+    source 64
+    target 60
+    value 2
+  ]
+  edge
+  [
+    source 64
+    target 59
+    value 9
+  ]
+  edge
+  [
+    source 64
+    target 57
+    value 1
+  ]
+  edge
+  [
+    source 64
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 65
+    target 63
+    value 5
+  ]
+  edge
+  [
+    source 65
+    target 64
+    value 7
+  ]
+  edge
+  [
+    source 65
+    target 48
+    value 3
+  ]
+  edge
+  [
+    source 65
+    target 62
+    value 5
+  ]
+  edge
+  [
+    source 65
+    target 58
+    value 5
+  ]
+  edge
+  [
+    source 65
+    target 61
+    value 5
+  ]
+  edge
+  [
+    source 65
+    target 60
+    value 2
+  ]
+  edge
+  [
+    source 65
+    target 59
+    value 5
+  ]
+  edge
+  [
+    source 65
+    target 57
+    value 1
+  ]
+  edge
+  [
+    source 65
+    target 55
+    value 2
+  ]
+  edge
+  [
+    source 66
+    target 64
+    value 3
+  ]
+  edge
+  [
+    source 66
+    target 58
+    value 3
+  ]
+  edge
+  [
+    source 66
+    target 59
+    value 1
+  ]
+  edge
+  [
+    source 66
+    target 62
+    value 2
+  ]
+  edge
+  [
+    source 66
+    target 65
+    value 2
+  ]
+  edge
+  [
+    source 66
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 66
+    target 63
+    value 1
+  ]
+  edge
+  [
+    source 66
+    target 61
+    value 1
+  ]
+  edge
+  [
+    source 66
+    target 60
+    value 1
+  ]
+  edge
+  [
+    source 67
+    target 57
+    value 3
+  ]
+  edge
+  [
+    source 68
+    target 25
+    value 5
+  ]
+  edge
+  [
+    source 68
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 68
+    target 24
+    value 1
+  ]
+  edge
+  [
+    source 68
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 68
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 68
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 69
+    target 25
+    value 6
+  ]
+  edge
+  [
+    source 69
+    target 68
+    value 6
+  ]
+  edge
+  [
+    source 69
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 69
+    target 24
+    value 1
+  ]
+  edge
+  [
+    source 69
+    target 27
+    value 2
+  ]
+  edge
+  [
+    source 69
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 69
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 70
+    target 25
+    value 4
+  ]
+  edge
+  [
+    source 70
+    target 69
+    value 4
+  ]
+  edge
+  [
+    source 70
+    target 68
+    value 4
+  ]
+  edge
+  [
+    source 70
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 70
+    target 24
+    value 1
+  ]
+  edge
+  [
+    source 70
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 70
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 70
+    target 58
+    value 1
+  ]
+  edge
+  [
+    source 71
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 71
+    target 69
+    value 2
+  ]
+  edge
+  [
+    source 71
+    target 68
+    value 2
+  ]
+  edge
+  [
+    source 71
+    target 70
+    value 2
+  ]
+  edge
+  [
+    source 71
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 71
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 71
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 71
+    target 25
+    value 1
+  ]
+  edge
+  [
+    source 72
+    target 26
+    value 2
+  ]
+  edge
+  [
+    source 72
+    target 27
+    value 1
+  ]
+  edge
+  [
+    source 72
+    target 11
+    value 1
+  ]
+  edge
+  [
+    source 73
+    target 48
+    value 2
+  ]
+  edge
+  [
+    source 74
+    target 48
+    value 2
+  ]
+  edge
+  [
+    source 74
+    target 73
+    value 3
+  ]
+  edge
+  [
+    source 75
+    target 69
+    value 3
+  ]
+  edge
+  [
+    source 75
+    target 68
+    value 3
+  ]
+  edge
+  [
+    source 75
+    target 25
+    value 3
+  ]
+  edge
+  [
+    source 75
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 75
+    target 41
+    value 1
+  ]
+  edge
+  [
+    source 75
+    target 70
+    value 1
+  ]
+  edge
+  [
+    source 75
+    target 71
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 64
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 65
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 66
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 63
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 62
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 48
+    value 1
+  ]
+  edge
+  [
+    source 76
+    target 58
+    value 1
+  ]
+]
diff --git a/src/Algebra/Graph/IO/GML.hs b/src/Algebra/Graph/IO/GML.hs
new file mode 100644
--- /dev/null
+++ b/src/Algebra/Graph/IO/GML.hs
@@ -0,0 +1,105 @@
+{-# language OverloadedStrings #-}
+{-# options_ghc -Wno-unused-imports #-}
+-- | Mostly-complete implementation of the GML format
+--
+-- https://en.wikipedia.org/wiki/Graph_Modelling_Language
+module Algebra.Graph.IO.GML (gmlGraph, gmlGraphP, GMLGraph(..), GMLNode(..), GMLEdge(..)) where
+
+import Control.Applicative hiding (many, some)
+import Data.Char (isAlpha, isSpace)
+import Data.Functor (void)
+import Data.Void (Void)
+
+-- algebraic-graphs
+import qualified Algebra.Graph as G (Graph, empty, vertex, edge, overlay)
+-- megaparsec
+import Text.Megaparsec (Parsec, parse, parseTest, satisfy, (<?>))
+import Text.Megaparsec.Char (space1)
+import qualified Text.Megaparsec.Char.Lexer as L
+-- parser-combinators
+import Control.Monad.Combinators (many, some, between, skipManyTill)
+-- text
+import Data.Text (Text)
+import Data.Text.IO (readFile)
+
+import Prelude hiding (readFile, takeWhile)
+
+import Algebra.Graph.IO.Internal.Megaparsec (Parser, lexeme, symbol, anyString)
+
+-- | Construct a 'G.Graph' using the edge data contained in a 'GMLGraph'
+gmlGraph :: GMLGraph a b -> G.Graph a
+gmlGraph (GMLGraph _ _ es) =
+  foldl (\gr (GMLEdge a b _ _) -> G.edge a b `G.overlay` gr) G.empty es
+
+-- | Graph entities of the GML graph format
+data GMLGraph a b = GMLGraph {
+  gmlHeader :: Maybe String
+  , gmlNodes :: [GMLNode a]
+  , gmlEdges :: [GMLEdge a b]
+  } deriving (Show)
+
+-- | Parser for the GML graph format
+gmlGraphP :: Parser a -- ^ parser for node id's
+          -> Parser b
+          -> Parser (GMLGraph a b)
+gmlGraphP p p2 = do
+  header <- optional creator -- header
+  void $ symbol "graph"
+  sqBkts $ do
+    ns <- many $ gmlNode p
+    es <- many $ gmlEdge p p2
+    pure $ GMLGraph header ns es
+
+creator :: Parser String
+creator = do
+  void $ symbol "Creator"
+  quoted $ many $ satisfy (/= '\"')
+
+-- | GML nodes
+data GMLNode a = GMLNode a (Maybe String) deriving (Show)
+
+gmlNode :: Parser a -> Parser (GMLNode a)
+gmlNode p = do
+  void $ symbol "node"
+  sqBkts $ do
+    n <- symbol "id" *> lexeme p
+    l <- optional gmlLabel
+    pure $ GMLNode n l
+
+sqBkts :: Parser a -> Parser a
+sqBkts = between (symbol "[") (symbol "]")
+quoted :: Parser a -> Parser a
+quoted = between (symbol "\"") (symbol "\"")
+
+-- | GML edges
+data GMLEdge a b = GMLEdge a a (Maybe b) (Maybe String) deriving (Show)
+
+gmlEdge :: Parser a -> Parser b -> Parser (GMLEdge a b)
+gmlEdge pa pb = do
+  void $ symbol "edge"
+  sqBkts $ do
+    a <- source pa
+    b <- target pa
+    v <- optional (value pb)
+    l <- optional gmlLabel
+    pure $ GMLEdge a b v l
+
+-- attributes
+
+source, target, value :: Parser a -> Parser a
+source = attr "source"
+target = attr "target"
+value = attr "value"
+
+gmlLabel :: Parser String
+gmlLabel = symbol "label" *> lexeme (quoted p)
+  where
+    p = many $ satisfy (/= '\"')
+
+attr :: Text -> Parser a -> Parser a
+attr str p = symbol str *> lexeme p
+
+
+-- gmlValue :: Parser a -> Parser a
+-- gmlValue p = symbol "value" *> lexeme p
+
diff --git a/src/Algebra/Graph/IO/Internal/Megaparsec.hs b/src/Algebra/Graph/IO/Internal/Megaparsec.hs
new file mode 100644
--- /dev/null
+++ b/src/Algebra/Graph/IO/Internal/Megaparsec.hs
@@ -0,0 +1,34 @@
+{-# language OverloadedStrings #-}
+{-# options_ghc -Wno-unused-imports #-}
+module Algebra.Graph.IO.Internal.Megaparsec where
+
+import Control.Applicative hiding (many, some)
+import Data.Char (isAlpha, isSpace)
+import Data.Void (Void)
+
+-- megaparsec
+import Text.Megaparsec (Parsec, parseTest, satisfy, (<?>))
+import Text.Megaparsec.Char (space1)
+import qualified Text.Megaparsec.Char.Lexer as L
+-- parser-combinators
+import Control.Monad.Combinators (many, some, between)
+-- text
+import Data.Text (Text)
+
+type Parser = Parsec Void Text
+
+lexeme :: Parser a -> Parser a
+lexeme = L.lexeme sc
+
+symbol :: Text -> Parser Text
+symbol = L.symbol sc
+
+-- space consumer
+sc :: Parser ()
+sc = L.space
+     space1
+     (L.skipLineComment "//")
+     (L.skipBlockComment "/*" "*/")
+
+anyString :: Parser String
+anyString = many (satisfy isAlpha)
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
