diff --git a/morphisms/runtime/include/array/length-prefix.h b/morphisms/runtime/include/array/length-prefix.h
index 35a4aec..3f039f2 100644
--- a/morphisms/runtime/include/array/length-prefix.h
+++ b/morphisms/runtime/include/array/length-prefix.h
@@ -7,22 +7,22 @@
     typedef struct {                                                           \
         LEN_TYPE len;                                                          \
         ITEM_TYPE items[];                                                     \
-    } LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE;                             \
+    } __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_;                             \
                                                                                \
     static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear(   \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data) {                   \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) {                   \
         data->len = 0;                                                         \
     }                                                                          \
                                                                                \
     static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push(    \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data,                     \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data,                     \
         ITEM_TYPE value) {                                                     \
         data->items[data->len++] = value;                                      \
     }                                                                          \
                                                                                \
     static inline int length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_reverse(  \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * restrict src,      \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *restrict dst) {           \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * restrict src,      \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *restrict dst) {           \
         for (LEN_TYPE i = 0; i < src->len; i++) {                              \
             dst->items[i] = src->items[src->len - 1 - i];                      \
         }                                                                      \
@@ -31,59 +31,10 @@
     }                                                                          \
                                                                                \
     static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_dump(    \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * data) {            \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) {            \
         printf("Length: %llu\n", (unsigned long long) data->len);              \
         for (LEN_TYPE i = 0; i < data->len; i++) {                             \
             printf("%llu ", (unsigned long long) data->items[i]);              \
         }                                                                      \
         printf("\n");                                                          \
     }
-
-#define DEFINE_ALL_LENGTH_PREFIX_ARRAYS(LEN_TYPE)  \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint64_t)
-
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint8_t)
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint16_t)
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint32_t)
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint64_t)
-
-
-#define DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, SRC_ITEM_TYPE, DST_ITEM_TYPE) \
-    static inline int length_prefix_##LEN_TYPE##_array_map_##SRC_ITEM_TYPE##_to_##DST_ITEM_TYPE( \
-        int (*f)(SRC_ITEM_TYPE const * restrict, DST_ITEM_TYPE * restrict),    \
-        LengthPrefix_##LEN_TYPE##_Array_##SRC_ITEM_TYPE const * restrict src,  \
-        LengthPrefix_##LEN_TYPE##_Array_##DST_ITEM_TYPE * restrict dst)        \
-    {                                                                          \
-        if (dst->len < src->len) return -1; /* Ensure enough space */          \
-        for (LEN_TYPE i = 0; i < src->len; i++) {                              \
-            if (f(&src->items[i], &dst->items[i]) != 0) return -1;             \
-        }                                                                      \
-        dst->len = src->len;                                                   \
-        return 0;                                                              \
-    }
-
-#define DEFINE_ALL_MAPS(LEN_TYPE)                        \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint8_t)   \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint16_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint32_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint64_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint64_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint64_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint64_t)
-
-DEFINE_ALL_MAPS(uint8_t)
-DEFINE_ALL_MAPS(uint16_t)
-DEFINE_ALL_MAPS(uint32_t)
-DEFINE_ALL_MAPS(uint64_t)
diff --git a/src/c_gen.rs b/src/c_gen.rs
index 41d1c99..0f21ef8 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -1,9 +1,16 @@
 use {
-    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_arg_ty, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
+    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_value, get_c_repr_arg_type,
+        get_c_repr_definition, get_c_repr_type}, morphism::LdmcPrimMorph,
+    struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}},
+    chumsky::{chain::Chain, primitive::Container},
+    laddertypes::{morphism::{MorphismInstance, Morphism, MorphismType},
+        parser::*, substitution::Substitution, unparser::*,
+        EnumVariant, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm},
+    std::collections::HashMap
 };
 
 impl LdmcPrimMorph {
-    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> String {
+    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> String {
         let mut s = self.symbol.clone();
         for (k_id,v) in self.type_args.iter() {
 
@@ -14,7 +21,7 @@ impl LdmcPrimMorph {
                         //self.get_type().strip_halo().dst_type.contains_var(*var_id) {
 
                             let name = dict.get_varname(*var_id).unwrap();
-                            let val_str = encode_type_to_symbol(dict, &val_trm);
+                            let val_str = get_c_repr_type(dict, &val_trm);
                             s.push_str(&format!("_{}_{}", name, val_str));
 
                             //}
@@ -31,20 +38,26 @@ impl LdmcPrimMorph {
     }
 
     pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
-        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::SugaredTypeTerm>
+        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>
     ) -> String {
         format!("int {} ({} const * restrict src, {} * restrict dst);",
             self.instantiated_symbol_name(dict, σ),
-            get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
-            get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
+            get_c_repr_definition(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
+            get_c_repr_definition(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
     }
 
-    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> Option<String> {
+    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> Option<String> {
         let mut s = String::new();
         let symbol = self.instantiated_symbol_name(dict, σ);
 
-        let src_c_symbol = encode_type_to_arg_ty(dict, &self.ty.strip_halo().src_type.clone().apply_subst(σ).get_floor_type().1);
-        let dst_c_symbol = encode_type_to_arg_ty(dict, &self.ty.strip_halo().dst_type.clone().apply_subst(σ).get_floor_type().1);
+        eprintln!("generate instantiation:");
+        let ty = self.ty.clone();
+        eprintln!("full type: {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
+        let ty = ty.strip_halo().apply_subst(σ);
+        eprintln!("stripped type:  {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
+
+        let src_c_symbol = get_c_repr_arg_type(dict, &ty.src_type);
+        let dst_c_symbol = get_c_repr_arg_type(dict, &ty.dst_type);
 
         s.push_str(&format!(r#"
 int {} ( {} const * restrict src, {} * restrict dst ) {{
@@ -66,8 +79,9 @@ int {} ( {} const * restrict src, {} * restrict dst ) {{
 
 pub struct LdmcCTargetMorph {
     includes: Vec< String >,
-    active_types: Vec< SugaredTypeTerm >,
+    active_types: Vec< TypeTerm >,
     active_instantiations: Vec< LdmcPrimMorph >,
+    macro_calls: Vec< String >
 }
 
 impl LdmcCTargetMorph {
@@ -75,18 +89,42 @@ impl LdmcCTargetMorph {
         LdmcCTargetMorph {
             includes: vec![
                 "#include <stdint.h>".into(),
+                "#include <array/length-prefix.h>".into(),
                 "#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }".into(),
             ],
             active_instantiations: Vec::new(),
             active_types: Vec::new(),
+            macro_calls: Vec::new()
         }
     }
 
-    pub fn add_type(&mut self, ty: SugaredTypeTerm) {
+    pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) {
+        let ty = ty.strip();
         if ! self.active_types.contains(&ty) {
+            eprintln!("add type {:?}", ty);
             match &ty {
-                SugaredTypeTerm::Seq { seq_repr, items } =>{
-                    self.add_type(items.first().unwrap().clone());
+                TypeTerm::Seq { seq_repr, items } =>{
+                    let item_type = items.first().unwrap().clone();
+                    self.add_type(dict, item_type.clone());
+
+                    if let Some(seq_repr) = seq_repr {
+                        dict.add_varname("LengthType".into());
+                        if let Ok(σ) =
+                            laddertypes::constraint_system::unify(
+                                seq_repr.as_ref(),
+                                &dict.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(dict)
+                            )
+                        {
+                            let length_type = σ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get Length type");
+                            self.add_type(dict, length_type.clone());
+                            self.macro_calls.push(
+                                format!("DEFINE_LENGTH_PREFIX_ARRAY({}, {})\n",
+                                    get_c_repr_type(dict, &length_type),
+                                    get_c_repr_type(dict, &item_type)
+                                )
+                            );
+                        }
+                    }
                 }
                 _=>{}
             }
@@ -97,7 +135,7 @@ impl LdmcCTargetMorph {
     pub fn add_instantiation(
         &mut self,
         dict: &mut impl TypeDict,
-        morph: MorphismInstance2<LdmcPrimMorph>,
+        morph: MorphismInstance<LdmcPrimMorph>,
     ) -> Result<LdmcPrimMorph, ()> {
         let new_inst = self.bake_morphism(dict, morph)?;
         if ! self.active_instantiations.contains(&new_inst) {
@@ -105,44 +143,58 @@ impl LdmcCTargetMorph {
         }
 
         let ty = new_inst.get_type().strip_halo();
-        self.add_type(ty.src_type.get_floor_type().1);
-        self.add_type(ty.dst_type.get_floor_type().1);
+        self.add_type(dict, ty.src_type);
+        self.add_type(dict, ty.dst_type);
 
         Ok(new_inst)
     }
 
-    pub fn into_c_source(self, dict: &mut impl TypeDict) -> String {
+    pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
         let mut source = String::new();
+        self.includes.dedup();
+        self.macro_calls.dedup();
+        self.active_types.dedup();
+
         for inc in self.includes {
             source.push_str(&inc);
             source.push('\n');
         }
 
+        source.push('\n');
+
         for ty in self.active_types {
-            source.push_str(&format!("
-    typedef {} {};
-",
-                get_c_repr_type(dict, ty.clone(), false).expect(&format!("cant get c-repr type for type '{}'", ty.pretty(dict,0))),
-                encode_type_to_symbol(dict, &ty)));
+            if let Some(type_def) = get_c_repr_definition(dict, ty.clone(), false) {
+                let type_name = get_c_repr_type(dict, &ty);
+                source.push_str(&format!("typedef {} {};\n", type_def, type_name));
+            } else {
+                eprintln!("cant get c-repr type for type '{}'", ty.pretty(dict,0));
+            }
         }
+        source.push('\n');
+
+
+        for m in self.macro_calls {
+            source.push_str(&m);
+            source.push('\n');
+        }
+        source.push('\n');
 
         for m in self.active_instantiations {
             source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
         }
-
         source
     }
 
     pub fn bake_morphism(
         &mut self,
         dict: &mut impl laddertypes::TypeDict,
-        morph_inst: MorphismInstance2<LdmcPrimMorph>,
+        morph_inst: MorphismInstance<LdmcPrimMorph>,
     ) -> Result<LdmcPrimMorph, ()> {
-        eprintln!("bake morphism:  {}
-  ------> {}", morph_inst.get_haloless_type().src_type.pretty(dict,0), morph_inst.get_haloless_type().dst_type.pretty(dict, 0));
+        let ty = morph_inst.get_type();
+        let symbol = encode_morph_type_to_symbol(dict, &ty);
 
         match &morph_inst {
-            MorphismInstance2::Primitive { ψ, σ, morph } => {
+            MorphismInstance::Primitive { ψ, σ, morph } => {
                 let mut c_source = String::new();
                 for (ty_id, kind) in morph.type_args.iter() {
                     if let laddertypes::TypeID::Var(var_id) = ty_id {
@@ -150,7 +202,7 @@ impl LdmcCTargetMorph {
                         //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
                             if let Some(val) = σ.get(ty_id) {
                                 let type_var_value =
-                                    if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
+                                    if let Some(c_repr_type) = get_c_repr_definition(dict, val.clone(), true) {
                                         c_repr_type
                                     } else {
                                         encode_type_to_value(dict, &val)
@@ -179,10 +231,7 @@ impl LdmcCTargetMorph {
                     c_source
                 })
             },
-            MorphismInstance2::Chain { path } => {
-                let ty = morph_inst.get_type().strip_halo();
-                let symbol = encode_morph_type_to_symbol(dict, &ty);
-
+            MorphismInstance::Chain { path } => {
                 let mut c_source = String::new();
 
                 if path.len() > 1 {
@@ -195,8 +244,8 @@ impl LdmcCTargetMorph {
                 for (i,morph) in path.iter().enumerate() {
                     if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
                         let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
-                        let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
-                        let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
+                        let src_buf = if i == 0 { "(void*)src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
+                        let dst_buf = if i+1 == path.len() { "(void*)dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
 
                         c_source.push_str(&format!(r#"
         FUSE( {}, {}, {} );"#,
@@ -213,30 +262,28 @@ impl LdmcCTargetMorph {
                     c_source
                 })
             }
-            MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
+            MorphismInstance::MapSeq { ψ, seq_repr, item_morph } => {
                 if let Ok(item_morph_inst) = self.add_instantiation(dict, item_morph.as_ref().clone()) {
                     if let Some(seq_repr) = seq_repr {
                         dict.add_varname("Length".into());
                         dict.add_varname("LengthType".into());
                         dict.add_varname("TerminatorValue".into());
 
-                        if let Ok(γ) = laddertypes::unification_sugared::unify(
-                            &dict.parse("<StaticLength Length>").expect("parse type template").sugar(dict),
+                        if let Ok(γ) = laddertypes::constraint_system::unify(
+                            &dict.parse_desugared("<StaticLength Length>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
                             let length = γ.get(&dict.get_typeid(&"Length".into()).expect("")).expect("cant get Length");
                             match length {
-                                SugaredTypeTerm::Num(l) => {
-                                    let ty = morph_inst.get_type().strip_halo();
-                                    let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_type());
+                                TypeTerm::Num(l) => {
                                     let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
 
-                                    self.add_type( morph_inst.get_type().strip_halo().src_type );
-                                    self.add_type( morph_inst.get_type().strip_halo().dst_type );
+                                    self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
+                                    self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
 
                                     let c_source = format!(r#"
                                         for( size_t i = 0; i < {}; ++i ) {{
-                                            FUSE( {}, &src[i], &dst[i] );
+                                            FUSE( {}, &src->items[i], &dst->items[i] );
                                         }}
                                         "#,
                                         l,
@@ -255,19 +302,16 @@ impl LdmcCTargetMorph {
                             }
                         }
 
-                        else if let Ok(γ) = laddertypes::unification_sugared::unify(
-                            &dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
+                        else if let Ok(γ) = laddertypes::constraint_system::unify(
+                            &dict.parse_desugared("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
                             // todo: assert that length type is native.UIntX
                             //let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
-
-                            let ty = morph_inst.get_type().strip_halo();
-                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_type());
                             let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
 
-                            self.add_type( morph_inst.get_type().strip_halo().src_type );
-                            self.add_type( morph_inst.get_type().strip_halo().dst_type );
+                            self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
+                            self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
 
                             let c_source = format!(r#"
                                 for( size_t i = 0; i < src->len; ++i ) {{
@@ -284,13 +328,11 @@ impl LdmcCTargetMorph {
                             })
                         }
 
-                        else if let Ok(γ) = laddertypes::unification_sugared::unify(
-                            &dict.parse("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
+                        else if let Ok(γ) = laddertypes::constraint_system::unify(
+                            &dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
                             let terminator_value = γ.get(&dict.get_typeid(&"TerminatorValue".into()).expect("")).expect("cant get TerminatorValue");
-                            let ty = morph_inst.get_type().strip_halo();
-                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
                             let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
                             let terminator = encode_type_to_value(dict, terminator_value);
 
@@ -326,9 +368,7 @@ impl LdmcCTargetMorph {
                     Err(())
                 }
             },
-            MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => {
-                let ty = morph_inst.get_type().strip_halo();
-                let symbol =encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+            MorphismInstance::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => {
 
                 let mut c_source = String::new();
 
@@ -337,8 +377,7 @@ impl LdmcCTargetMorph {
                         let name = name.replace("-", "_").replace(".","_dot_");
                         c_source.push_str(
                             &format!("
-                                FUSE( {}, &src->{}, &dst->{} );
-                            ",
+        FUSE( {}, &src->{}, &dst->{} );",
                             inst.symbol,
                             name, name
                         ));
@@ -354,49 +393,53 @@ impl LdmcCTargetMorph {
                     c_source
                 })
             }
-            MorphismInstance2::MapEnum { ψ, enum_repr, variant_morph } => {
+            MorphismInstance::MapEnum { ψ, enum_repr, variant_morph } => {
                 todo!();
             }
         }
     }
 }
 
-pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance2<LdmcPrimMorph>) -> Result<String, ()> {
+pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
     let mut target = LdmcCTargetMorph::new();
     let ty = morph.get_type();
-    if let Ok(inst) = target.add_instantiation(dict, morph) {
-        let mut c_source = target.into_c_source(dict);
+    match target.add_instantiation(dict, morph) {
+        Ok(inst) => {
+            let mut c_source = target.into_c_source(dict);
 
-        c_source.push_str(&format!(r#"
-    #include <unistd.h>
+            c_source.push_str(&format!(r#"
+        #include <unistd.h>
 
-    int main() {{
-        uint8_t bufIn[4096];
-        uint8_t bufOut[4096];"#));
+        int main() {{
+            uint8_t bufIn[4096];
+            uint8_t bufOut[4096];"#));
 
-        let (src_top, src_floor) = ty.src_type.get_floor_type();
-        if src_floor == dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
-            c_source.push_str("scanf(\"%s\", bufIn);");
-        } else {
-            c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+            let (src_top, src_floor) = ty.src_type.get_floor_type();
+            if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
+                c_source.push_str("scanf(\"%s\", bufIn);");
+            } else {
+                c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+            }
+
+            c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
+
+            if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                &ty.src_type,
+                &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
+            ) {
+                c_source.push_str("printf(\"%s\\n\", bufOut);");
+            } else {
+                c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+            }
+            c_source.push_str("
+            return 0;
+        }");
+
+            Ok(c_source)
         }
-
-        c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
-
-        if let Ok(ψ) = laddertypes::unification_sugared::subtype_unify(
-            &ty.src_type,
-            &dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
-        ) {
-            c_source.push_str("printf(\"%s\\n\", bufOut);");
-        } else {
-            c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+        Err(err) => {
+            eprintln!("failed to create morphism instatiation");
+            Err(())
         }
-        c_source.push_str("
-        return 0;
-    }");
-
-        Ok(c_source)
-    } else {
-        Err(())
     }
 }
diff --git a/src/c_gen_types.rs b/src/c_gen_types.rs
index 0fb3b0d..8c366bb 100644
--- a/src/c_gen_types.rs
+++ b/src/c_gen_types.rs
@@ -1,5 +1,9 @@
 use {
-    crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::chain::Chain, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}
+    crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}},
+    chumsky::chain::Chain, laddertypes::{morphism::{MorphismInstance, MorphismType},
+        parser::*,
+        substitution::Substitution,
+        unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm}, std::thread::yield_now
 };
 
 /*
@@ -13,9 +17,9 @@ pub fn get_c_repr_kind(kind: String) -> Option<String> {
 
 /* for a given ladder type `t`, get the corresponding C type
  */
-pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointer: bool) -> Option<String> {
-    match t.get_floor_type().1.strip() {
-        SugaredTypeTerm::TypeID(tyid) => {
+pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer: bool) -> Option<String> {
+    match t {
+        TypeTerm::TypeID(tyid) => {
             if tyid == dict.get_typeid_creat("native.UInt8") {
                 Some("uint8_t".into())
             } else if tyid == dict.get_typeid_creat("native.UInt16") {
@@ -35,20 +39,18 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
             }
         }
 
-        SugaredTypeTerm::Seq{ seq_repr, items } => {
-            if let Some(sr_sugar) = seq_repr {
-                let sr = sr_sugar.desugar(dict);
-
+        TypeTerm::Seq{ seq_repr, items } => {
+            if let Some(seq_repr) = seq_repr {
                 let item_type = items.first().expect("no item type specified!").clone();
-                let item_c_type : String = get_c_repr_type(dict, item_type, false).expect("cant get item type representation");
+                let item_c_type : String = get_c_repr_type(dict, &item_type);
 
                 dict.add_varname("Length".into()); // Kind: Num
                 dict.add_varname("LengthType".into()); // Kind: Type
                 dict.add_varname("TermValue".into()); // Kind: Value of Type ItemType
 
-                if let Ok(σ) = laddertypes::unify(
-                    &sr,
-                    &dict.parse("<StaticLength Length>").expect("parse")
+                if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("<StaticLength Length>").expect("parse template type").sugar(dict)
                 ) {
                     let length = match
                         σ.get(
@@ -61,46 +63,23 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
                             return None;
                         }
                     };
-                    Some(format!("{}[{}]", item_c_type, length))
+                    Some(format!("struct {{ {} items[{}]; }} ", item_c_type, length))
                 }
-                else if let Ok(σ) = laddertypes::unify(
-                    &sr,
-                    &dict.parse("<LengthPrefix LengthType>").expect("parse")
+                else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("<LengthPrefix LengthType>").expect("parse template type").sugar(dict)
                 ) {
                     let length_type = σ.get(
                             &dict.get_typeid(&"LengthType".into()).expect("no LengthType ID")
-                        ).expect("no length type specified")
-                        .clone()
-                        .sugar(dict);
-                    let length_c_type : String = get_c_repr_type(dict, length_type, false).expect("cant get length type representation");
+                        ).expect("no length type specified");
 
-                    match length_c_type.as_str() {
-                        "uint8_t" |
-                        "uint16_t" |
-                        "uint32_t" |
-                        "uint64_t" => {}
-                        s => {
-                                eprintln!("invalid length type '{}' !", s);
-                                return None;
-                            }
-                        }
-                        match item_c_type.as_str() {
-                            "uint8_t" |
-                            "uint16_t" |
-                            "uint32_t" |
-                            "uint64_t" |
-                            "void*" => {}
-                            s => {
-                                eprintln!("invalid item type '{}'!", s);
-                                return None;
-                        }
-                    }
+                    let length_c_type = get_c_repr_type(dict, &length_type);
 
-                    Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
+                    Some(format!("struct {{ {} len; {} items[]; }} ", length_c_type, item_c_type))
                 }
-                else if let Ok(σ) = laddertypes::unify(
-                    &sr,
-                    &dict.parse("<ValueTerminated TermValue>").expect("")
+                else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("<ValueTerminated TermValue>").expect("parse template type").sugar(dict)
                 ) {
                     if skip_pointer {
                         Some(item_c_type)
@@ -109,7 +88,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
                     }
                 }
                 else {
-                    eprintln!("can't get C-repr for sequence type `{}`!", dict.unparse(&sr));
+                    eprintln!("can't get C-repr for sequence type `{}`!", seq_repr.pretty(dict, 0));
                     None
                 }
             } else {
@@ -118,7 +97,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
             }
         }
 
-        SugaredTypeTerm::Struct{ struct_repr, members } => {
+        TypeTerm::Struct{ struct_repr, members } => {
             let c_struct_attribute =
                 if let Some(sr) = struct_repr {
                     let sr = sr.desugar(dict);
@@ -130,8 +109,8 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
 
             let mut c_type = format!("struct {} {{\n", c_struct_attribute);
 
-            for SugaredStructMember{ symbol, ty } in members {
-                let field_c_type = get_c_repr_type(dict, ty, false).expect("");
+            for StructMember{ symbol, ty } in members {
+                let field_c_type = get_c_repr_definition(dict, ty, false).expect("");
                 c_type.push_str(&format!("    {} {};\n",
                     field_c_type,
                     symbol.replace("-", "_").replace(".","_dot_")
@@ -142,13 +121,13 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
             Some(c_type)
         }
 
-        SugaredTypeTerm::Enum { enum_repr, variants } => {
+        TypeTerm::Enum { enum_repr, variants } => {
             let mut c_type = format!("
 struct {{
     enum {{
 ");
 
-            for (i, SugaredEnumVariant{ symbol, ty }) in variants.iter().enumerate() {
+            for (i, EnumVariant{ symbol, ty }) in variants.iter().enumerate() {
                 c_type.push_str(&format!(
                     "       {} = {}", symbol.replace("-", "_").replace(".","_dot_").to_uppercase(), i
                 ));
@@ -164,8 +143,8 @@ struct {{
     union {
 ");
 
-            for SugaredEnumVariant{ symbol, ty } in variants {
-                let variant_c_type = get_c_repr_type(dict, ty, false).expect("cant get C-Repr type for variant");
+            for EnumVariant{ symbol, ty } in variants {
+                let variant_c_type = get_c_repr_definition(dict, ty, false).expect("cant get C-Repr type for variant");
                 c_type.push_str(&format!(
                     "       {} {};\n", variant_c_type, symbol.replace("-", "_").replace(".","_dot_")
                 ));
@@ -178,9 +157,9 @@ struct {{
             Some(c_type)
         }
 
-        SugaredTypeTerm::Ladder(rungs) => {
+        TypeTerm::Ladder(rungs) => {
             if let Some(t) = rungs.last() {
-                get_c_repr_type(dict, t.clone(), false)
+                get_c_repr_definition(dict, t.clone(), false)
             } else {
                 None
             }
@@ -190,10 +169,11 @@ struct {{
     }
 }
 
-pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm)-> String {
-    let t = t.clone().desugar(dict);
-    match t {
-        laddertypes::TypeTerm::Char(c) => {
+pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
+    let t = t.clone().strip();
+
+    match t.desugar(dict) {
+        laddertypes::DesugaredTypeTerm::Char(c) => {
             match c {
                 '.' => format!("_dot_"),
                 '-' => format!("_minus_"),
@@ -201,57 +181,61 @@ pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredT
                 format!("{}", (c as u64))
             }
         },
-        laddertypes::TypeTerm::Num(n) => {
+        laddertypes::DesugaredTypeTerm::Num(n) => {
             format!("{}", n)
         }
-        laddertypes::TypeTerm::TypeID(ty_id) => {
+        laddertypes::DesugaredTypeTerm::TypeID(ty_id) => {
             if let Some(name) = dict.get_typename(&ty_id) {
                 name
                     .replace("-", "_")
-                    .replace(".", "_dot_")
+                    .replace(".", "")
             } else {
                 format!("")
             }
         }
-        laddertypes::TypeTerm::Ladder(rs) |
-        laddertypes::TypeTerm::App(rs) => {
+        laddertypes::DesugaredTypeTerm::Ladder(rs) |
+        laddertypes::DesugaredTypeTerm::App(rs) => {
             let mut s = String::new();
+            s.push('_');
             for r in rs {
-                s.push('_');
-
                 let r = r.sugar(dict);
-                s.push_str(&encode_type_to_symbol(dict, &r));
+                s.push_str(&get_c_repr_type(dict, &r));
+                s.push('_');
             }
             s
         }
     }
 }
 
-pub fn encode_type_to_arg_ty(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
-    match t.get_floor_type().1 {
-        SugaredTypeTerm::Seq { seq_repr, items } => {
-
-            if let Some(seq_repr) = seq_repr {
-                if seq_repr.as_ref() == &dict.parse("<ValueTerminated 0>").expect("").sugar(dict) {
-                    return encode_type_to_symbol(dict, items.first().unwrap());
+pub fn get_c_repr_arg_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
+    let t = t.clone().strip().get_floor_type().1;
+    dict.add_varname("TerminatorValue".into());
+    match &t {
+        TypeTerm::Seq { seq_repr, items } => {
+            if let Some(seq_repr) = seq_repr.as_ref() {
+                if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr,
+                    &dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("").sugar(dict)
+                ) {
+                    return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
                 }
             }
         }
-        _=>{}
-    }
 
-    encode_type_to_symbol(dict, t)
+        _ => {}
+    }
+    get_c_repr_type(dict, &t)
 }
 
-pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &SugaredMorphismType) -> String {
+pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &MorphismType) -> String {
     format!(
-        "morph_{}__to_{}",
-        encode_type_to_symbol(dict, &t.src_type),
-        encode_type_to_symbol(dict, &t.dst_type)
+        "morph__{}___TO__{}",
+        get_c_repr_type(dict, &t.strip_halo().src_type),
+        get_c_repr_type(dict, &t.strip_halo().dst_type)
     )
 }
 
-pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
+pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
     let t = t.clone().desugar(dict);
     dict.unparse(&t)
 }
diff --git a/src/main.rs b/src/main.rs
index df68e51..1e418d4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,14 +11,15 @@ use {
         morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
     }, ariadne::{Color, Label, Report, ReportKind, Source}, c_gen::LdmcCTargetMorph, chumsky::prelude::*, laddertypes::{
-        morphism_path_sugared::SugaredShortestPathProblem, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, SugaredTypeTerm, TypeDict
+        morphism_path::ShortestPathProblem, morphism::{MorphismInstance, Morphism, MorphismType},
+        parser::ParseLadderType, unparser::*, BimapTypeDict, TypeTerm, TypeDict
     }, std::{collections::HashMap, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi
 };
 
 fn main() {
     let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
 
-    let mut morphism_base = laddertypes::morphism_base_sugared::SugaredMorphismBase::<LdmcPrimMorph>::new();
+    let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcPrimMorph>::new();
 
     let mut args = std::env::args().skip(1);
     let src_type_arg = args.next().expect("src type expected");
@@ -95,7 +96,7 @@ fn main() {
     let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
     let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
 
-    let ty = SugaredMorphismType{ src_type: src_type.sugar(&mut type_dict), dst_type: dst_type.sugar(&mut type_dict) };
+    let ty = MorphismType{ src_type: src_type, dst_type };
     let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
     println!("{}", crate::c_gen::generate_main(&mut type_dict, m).expect("failed to generate main function"));
 }
diff --git a/src/morphism.rs b/src/morphism.rs
index 1fb4199..6e94477 100644
--- a/src/morphism.rs
+++ b/src/morphism.rs
@@ -1,177 +1,17 @@
 
-use laddertypes::{morphism::Morphism, morphism_base::MorphismBase, morphism_path::ShortestPathProblem, morphism_sugared::{SugaredMorphism, SugaredMorphismType}, SugaredStructMember};
-use crate::{c_gen_types::encode_type_to_symbol, struct_layout::StructLayout};
+use laddertypes::{morphism_path::ShortestPathProblem, morphism::{Morphism, MorphismType}, StructMember};
+use crate::{c_gen_types::get_c_repr_type, struct_layout::StructLayout};
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct LdmcPrimMorph {
     pub symbol: String,
     pub type_args: Vec<(laddertypes::TypeID, String)>,
-    pub ty: SugaredMorphismType,
+    pub ty: MorphismType,
     pub c_source: String
 }
 
-impl LdmcPrimMorph {
-    /*
-    pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String) -> LdmcPrimCMorphism {
-
-        let src_c_type = ;
-        let dst_c_type = ;
-
-        let c_source =
-            format!("
-                int {} ( {} const * restrict src, {} * restrict dst ) {{
-                    {}
-                    return 0;
-                }}
-                ",
-                symbol, src_c_type, dst_c_type,
-                self.generate_call(dict, &std::collections::HashMap::new(), 0)
-            );
-
-        LdmcPrimCMorphism {
-            symbol,
-            type_args: Vec::new(),
-            src_type,
-            dst_type,
-            c_source
-        }
-    }
-*/
-/*
-
-    pub fn new_struct_map(
-        dict: &mut impl laddertypes::TypeDict,
-        morph_base: &MorphismBase<LdmcPrimMorph>,
-        src: laddertypes::TypeTerm,
-        dst: laddertypes::TypeTerm,
-    ) -> Self {
-        let src_struct = StructLayout::parse(dict, &src).expect("cant parse src struct layout");
-        let dst_struct = StructLayout::parse(dict, &dst).expect("cant parse dst struct layout");
-
-        let mut member_morphisms = Vec::new();
-
-        for SugaredStructMember{ symbol: field_name, ty: dst_type } in dst_struct.members.iter() {
-            let mut src_type = None;
-            for SugaredStructMember{ symbol: src_name, ty: st } in src_struct.members.iter() {
-                if src_name == field_name {
-                    src_type = Some(st.clone());
-                }
-            }
-            let src_type = src_type.expect(&format!("cant find member {} in src struct", field_name));
-
-            if src_type == *dst_type {
-                member_morphisms.push(
-                    StructFieldMorphism {
-                        field_name: field_name.to_string(),
-                        item_morph: None,
-                        src_offset: src_struct.get_offset( field_name ),
-                        dst_offset: dst_struct.get_offset( field_name ),
-                    }
-                );
-            } else {
-                match ShortestPathProblem::new(
-                    &morph_base,
-                    laddertypes::MorphismType {
-                        src_type: src_type.clone().desugar(dict),
-                        dst_type: dst_type.clone().desugar(dict)
-                    }
-                ).solve()
-                {
-                    Some(path) => {
-
-                        let src_type = src_type.clone().desugar(dict);
-                        let dst_type = dst_type.clone().desugar(dict);
-
-                        let morph_symb = format!("morph_{}_to_{}",
-                            encode_type_to_symbol(dict, &src_type),
-                            encode_type_to_symbol(dict, &dst_type)
-                        );
-                        member_morphisms.push(
-                            StructFieldMorphism {
-                                field_name: field_name.to_string(),
-                                item_morph: None,//Some(Box::new(item_morph.m.into_prim_c_morphism(dict, morph_symb, &item_morph.σ))),
-                                src_offset: src_struct.get_offset( field_name ),
-                                dst_offset: dst_struct.get_offset( field_name ),
-                            }
-                        );
-                    },
-
-                    None => {
-                        eprintln!("cant map field {}", field_name);
-                    }
-                }
-            }
-        }
-
-        LdmcPrimMorph::StructMap {
-            src_struct, dst_struct,
-            member_morphisms
-        }
-    }
-    */
-}
-
-impl SugaredMorphism for LdmcPrimMorph {
-    fn get_type(&self) -> SugaredMorphismType {
+impl Morphism for LdmcPrimMorph {
+    fn get_type(&self) -> MorphismType {
         self.ty.clone()
     }
 }
-/*
-impl Morphism for LdmcMorphism {
-    fn weight(&self) -> u64 {
-        1
-    }
-
-    fn get_type(&self) -> laddertypes::MorphismType {
-        match self {
-            LdmcMorphism::Primitive(prim_morph) =>
-                laddertypes::MorphismType {
-                    src_type: prim_morph.src_type.clone().normalize(),
-                    dst_type: prim_morph.dst_type.clone().normalize()
-                },
-            LdmcMorphism::LengthPrefixMap{ length_prefix_type, item_morph } => {
-                laddertypes::MorphismType {
-                    src_type: laddertypes::TypeTerm::App(vec![ length_prefix_type.clone(), item_morph.src_type.clone() ]),
-                    dst_type: laddertypes::TypeTerm::App(vec![ length_prefix_type.clone(), item_morph.dst_type.clone() ]),
-                }
-            },
-            LdmcMorphism::ValueDelimMap{ delim, item_morph } => {
-                let value_delim_type = laddertypes::TypeTerm::App(vec![]);
-                laddertypes::MorphismType {
-                    src_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.src_type.clone() ]),
-                    dst_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.dst_type.clone() ]),
-                }
-            },
-            LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
-                laddertypes::MorphismType {
-                    src_type: src_struct.get_type(),
-                    dst_type: dst_struct.get_type()
-                }
-            }
-        }.normalize()
-    }
-
-    fn map_morphism(&self, seq_type: laddertypes::TypeTerm) -> Option< Self > {
-        match self {
-            LdmcMorphism::Primitive(prim) => {
-                let item_morph = Box::new(prim.clone());
-/*
-                if seq_type == self.length_prefix_type {
-                */
-                    Some(LdmcMorphism::LengthPrefixMap{
-                        length_prefix_type: seq_type,
-                        item_morph,
-                    })
-                    /*
-                } else if seq_type == self.value_delim_type {
-                    Some(LdmcMorphism::ValueDelimMap { delim, item_morph })
-                } else {
-                    None
-                }
-                */
-            }
-            _ => None
-        }
-    }
-}
-*/
diff --git a/src/parser.rs b/src/parser.rs
index 49320df..9590519 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,7 +1,7 @@
 use {
     crate::morphism::LdmcPrimMorph, chumsky::{
         prelude::*, text::*
-    }, laddertypes::{morphism_sugared::SugaredMorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
+    }, laddertypes::{morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
 };
 
 /* morphism-base text format:
@@ -59,13 +59,13 @@ pub fn morphism_base_parser(
                 ty_args.push((var_id, kind));
             }
 
-            let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
-            let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
+            let src_type = type_dict.parse_desugared(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
+            let dst_type = type_dict.parse_desugared(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
 
             LdmcPrimMorph {
                 symbol,
                 type_args: ty_args,
-                ty: SugaredMorphismType{
+                ty: MorphismType{
                     src_type,
                     dst_type
                 },
diff --git a/src/struct_layout.rs b/src/struct_layout.rs
index 40be995..3847814 100644
--- a/src/struct_layout.rs
+++ b/src/struct_layout.rs
@@ -1,7 +1,7 @@
 
 use std::ops::Deref;
 
-use laddertypes::{parser::*, unparser::*, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm};
+use laddertypes::{parser::*, unparser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
 
 #[derive(Clone, Copy, Debug)]
 pub enum ObjectSize {
@@ -46,9 +46,9 @@ impl std::ops::Mul for ObjectSize {
     }
 }
 
-pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectSize {
+pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
     match &ty {
-        SugaredTypeTerm::TypeID(tyid) => {
+        TypeTerm::TypeID(tyid) => {
                  if tyid == &dict.get_typeid_creat("native.UInt8") { ObjectSize::Static(1) }
             else if tyid == &dict.get_typeid_creat("native.UInt16") { ObjectSize::Static(2) }
             else if tyid == &dict.get_typeid_creat("native.UInt32") { ObjectSize::Static(4) }
@@ -61,23 +61,23 @@ pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectS
             }
         },
 
-        SugaredTypeTerm::Ladder(rungs) => {
+        TypeTerm::Ladder(rungs) => {
             get_type_size(dict, rungs.last().unwrap().clone() )
         }
 
-        SugaredTypeTerm::Struct { struct_repr, members } => {
+        TypeTerm::Struct { struct_repr, members } => {
             let layout = StructLayout::parse_sugared(dict, ty).expect("invalid struct");
             layout.get_size()
         }
 
-        SugaredTypeTerm::Seq { seq_repr, items } => {
+        TypeTerm::Seq { seq_repr, items } => {
             if let Some(seq_repr) = seq_repr {
                 dict.add_typename("Length".into());
                 dict.add_typename("LengthType".into());
                 dict.add_typename("TerminatorValue".into());
 
                 if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone().desugar(dict),
+                    &seq_repr.clone(),
                     &dict.parse("<StaticLength Length>").expect("")
                 ) {
                     if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_typeid(&"Length".into()).expect("")) {
@@ -87,13 +87,13 @@ pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectS
                     }
                 }
                 else if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone().desugar(dict),
+                    &seq_repr.clone(),
                     &dict.parse("<LengthPrefix LengthType>").expect("")
                 ) {
                     ObjectSize::Dynamic()
                 }
                 else if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone().desugar(dict),
+                    &seq_repr.clone(),
                     &dict.parse("<ValueTerminated TerminatorValue>").expect("")
                 ) {
                     ObjectSize::Dynamic()
@@ -118,35 +118,35 @@ pub enum LayoutType {
 }
 
 impl LayoutType {
-    pub fn parse( dict: &mut impl TypeDict, ty: &TypeTerm ) -> Option< LayoutType > {
-        if ty == &dict.parse("Aligned").expect("parse") {
+    pub fn parse( dict: &mut impl TypeDict, ty: &DesugaredTypeTerm ) -> Option< LayoutType > {
+        if ty == &dict.parse_desugared("Aligned").expect("parse") {
             Some(LayoutType::Aligned)
-        } else if ty == &dict.parse("Packed").expect("parse") {
+        } else if ty == &dict.parse_desugared("Packed").expect("parse") {
             Some(LayoutType::Packed)
         } else {
             None
         }
     }
 
-    pub fn unparse(&self, dict: &mut impl TypeDict) -> TypeTerm {
+    pub fn unparse(&self, dict: &mut impl TypeDict) -> DesugaredTypeTerm {
         match self {
-            LayoutType::Aligned => dict.parse("Aligned").unwrap(),
-            LayoutType::Packed => dict.parse("Packed").unwrap()
+            LayoutType::Aligned => dict.parse_desugared("Aligned").unwrap(),
+            LayoutType::Packed => dict.parse_desugared("Packed").unwrap()
         }
     }
 }
 
 #[derive(Clone)]
 pub struct StructLayout {
-    pub ty: laddertypes::TypeTerm,
+    pub ty: laddertypes::DesugaredTypeTerm,
     pub layout: LayoutType,
-    pub members: Vec< SugaredStructMember >,
+    pub members: Vec< StructMember >,
     offsets: std::collections::HashMap< String, u64 >,
     size: ObjectSize
 }
 
 impl StructLayout {
-    pub fn get_type(&self) -> TypeTerm {
+    pub fn get_type(&self) -> DesugaredTypeTerm {
         self.ty.clone()
     }
 
@@ -161,7 +161,7 @@ impl StructLayout {
     pub fn init_offsets(&mut self, dict: &mut impl TypeDict) {
         let mut offset = 0;
 
-        for SugaredStructMember{symbol: field_name, ty: field_type} in self.members.iter() {
+        for StructMember{symbol: field_name, ty: field_type} in self.members.iter() {
             //let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
             match get_type_size( dict, field_type.clone() ) {
                 ObjectSize::Static(field_size) => {
@@ -208,15 +208,15 @@ impl StructLayout {
         }
     }
 
-    pub fn parse(dict: &mut impl TypeDict, struct_type: &TypeTerm) -> Option <Self> {
+    pub fn parse(dict: &mut impl TypeDict, struct_type: &DesugaredTypeTerm) -> Option <Self> {
         let st = struct_type.clone().strip().param_normalize().sugar(dict);
         Self::parse_sugared(dict, st)
     }
 
-    pub fn parse_sugared(dict: &mut impl TypeDict, st: SugaredTypeTerm) -> Option <Self> {
+    pub fn parse_sugared(dict: &mut impl TypeDict, st: TypeTerm) -> Option <Self> {
         eprintln!("{}", st.pretty(dict, 0));
         match st.clone() {
-            SugaredTypeTerm::Struct{ struct_repr, members } => {
+            TypeTerm::Struct{ struct_repr, members } => {
                 let mut sl = StructLayout {
                     ty: st.desugar(dict),
                     layout: if let Some(sr) = struct_repr {