diff --git a/Cargo.toml b/Cargo.toml
index 8ebb199..bf945fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,3 +6,4 @@ edition = "2024"
 [dependencies]
 chumsky = "0.9.0"
 ariadne = "0.2"
+laddertypes = { path = "../lib-laddertypes", features = ["pretty"] }
diff --git a/src/main.rs b/src/main.rs
index 5df47b9..bcbda32 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,15 +2,21 @@ use {
     ariadne::{Color, Label, Report, ReportKind, Source},
     chumsky::{
         prelude::*, text::*
-    }
+    },
+    laddertypes::{
+        dict::TypeDict,
+        parser::ParseLadderType,
+        unparser::UnparseLadderType, BimapTypeDict
+    },
+    std::sync::{Arc, RwLock}
 };
 
 #[derive(Debug)]
 struct Morphism {
     symbol: String,
-    src_type: String,
-    dst_type: String,
     type_args: Vec<(String, String)>,
+    src_type: laddertypes::TypeTerm,
+    dst_type: laddertypes::TypeTerm,
     locations: Vec<String>
 }
 
@@ -20,7 +26,10 @@ struct Morphism {
  *     '-->' DST-TYPE
  *     '@' [ LOCATION ':' ]
  */
-fn parser() -> impl Parser<char, Vec<Morphism>, Error = Simple<char>> {
+fn parser(
+    type_dict: Arc<RwLock< BimapTypeDict >>
+) -> impl Parser<char, Vec<Morphism>, Error = Simple<char>> {
+
     ident().padded()
     .then(
         ident().padded()
@@ -37,16 +46,26 @@ fn parser() -> impl Parser<char, Vec<Morphism>, Error = Simple<char>> {
     .then(
         none_of(":\n").repeated().separated_by(just(':'))
     )
-    .map(|(((symbol, type_args), ((src_type, _), (dst_type, _))), locations)| {
-        Morphism {
-            symbol,
-            src_type: src_type.iter().collect(),
-            dst_type: dst_type.iter().collect(),
-            type_args: type_args.into_iter().map(|(v,k)| (v,k.into_iter().collect())).collect(),
-            locations: locations.into_iter().map(|l| l.into_iter().collect()).collect()
-        }
-    })
-    .separated_by(text::newline())
+    .map(
+        move |(((symbol, type_args), ((src_type, _), (dst_type, _))), locations)| {
+            let mut type_dict = type_dict.write().unwrap();
+            let type_args : Vec<_> = type_args.into_iter().map(|(v,k)| (v,k.into_iter().collect())).collect();
+            for (var, kind) in type_args.iter() {
+                type_dict.add_varname(var.clone());
+            }
+
+            let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
+            let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
+
+            Morphism {
+                symbol,
+                type_args,
+                src_type,
+                dst_type,
+                locations: locations.into_iter().map(|l| l.into_iter().collect()).collect()
+            }
+        })
+        .separated_by(text::newline())
 }
 
 fn main() {
@@ -59,21 +78,32 @@ fn main() {
         @lib/libmorph_posint.so:src/posint.c
 
         morph_string_as_nullterm_to_length_prefix ()
-            [~<ValueDelim '\0'> Char ~ Ascii]
-        --> [~<LengthPrefix x86.UInt64> Char ~ Ascii]
+            <Seq~<ValueDelim '\\0'> Char ~ Ascii>
+        --> <Seq~<LengthPrefix x86.UInt64> Char ~ Ascii>
         @lib/libmorph_length-prefix.so:src/length_prefix.c
 
         morph_string_as_length_prefix_to_nullterm ()
-            [~<LengthPrefix x86.UInt64> Char ~ Ascii]
-        --> [~<ValueDelim '\0'> Char ~ Ascii]
+            <Seq~<LengthPrefix x86.UInt64> Char ~ Ascii>
+        --> <Seq~<ValueDelim '\\0'> Char ~ Ascii>
         @lib/libmorph_length-prefix.so:src/length_prefix.c
     ";
 
-    let result = parser().parse(src);
+    let type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
+
+   let result = parser(type_dict.clone()).parse(src);
 
     match result {
         Ok(morphisms) => {
-            println!("parse ok.\n{:?}", morphisms);
+            println!("parse ok.");
+
+            let mut dict = type_dict.write().unwrap();
+
+            for m in morphisms {
+                println!("{}\n    {}\n---> \n    {}\n", m.symbol,
+                    m.src_type.normalize().sugar(&mut *dict).pretty(&mut *dict, 1),
+                    m.dst_type.normalize().sugar(&mut *dict).pretty(&mut *dict, 1),
+                );
+            }
         }
         Err(errs) => {
             errs.into_iter().for_each(|e| {