fn generalise(t: Type, ctx_level: usize) -> Type {
    match t {
        Type::Var { typ } => {
            let new_var = match &*typ.borrow() {
                TypeVar::Unbound { id, level } => {
                    let id = *id;
                    if *level > ctx_level {
                        return Type::Var {
                            typ: Rc::new(RefCell::new(TypeVar::Generic { id })),
                        };
                    } else {
                        Some(TypeVar::Unbound { id, level: *level })
                    }
                }

                TypeVar::Link { typ } => return generalise((**typ).clone(), ctx_level),

                TypeVar::Generic { .. } => None,
            };

            if let Some(v) = new_var {
                *typ.borrow_mut() = v;
            }
            Type::Var { typ }
        }

        Type::App {
            public,
            module,
            name,
            args,
        } => {
            let args = args.into_iter().map(|t| generalise(t, ctx_level)).collect();
            Type::App {
                public,
                module,
                name,
                args,
            }
        }

        Type::Fn { args, retrn } => {
            let args = args.into_iter().map(|t| generalise(t, ctx_level)).collect();
            let retrn = generalise(*retrn, ctx_level);
            Type::Fn {
                args,
                retrn: Box::new(retrn),
            }
        }

        Type::Tuple { elems } => Type::Tuple {
            elems: elems
                .into_iter()
                .map(|t| generalise(t, ctx_level))
                .collect(),
        },
    }
}
/// Takes a level and a type and turns all type variables within the type that have
/// level higher than the input level into generalized (polymorphic) type variables.
///
Takes a level and a type and turns all type variables within the type that have
level higher than the input level into generalized (polymorphic) type variables.
Takes a level and a type and turns all type variables within the type that have level higher than the input level into generalized ( polymorphic ) type variables .
fn generalise(t: Type, ctx_level: usize) -> Type {
    match t {
        Type::Var { typ } => {
            let new_var = match &*typ.borrow() {
                TypeVar::Unbound { id, level } => {
                    let id = *id;
                    if *level > ctx_level {
                        return Type::Var {
                            typ: Rc::new(RefCell::new(TypeVar::Generic { id })),
                        };
                    } else {
                        Some(TypeVar::Unbound { id, level: *level })
                    }
                }
                TypeVar::Link { typ } => return generalise((**typ).clone(), ctx_level),
                TypeVar::Generic { .. } => None,
            };
            if let Some(v) = new_var {
                *typ.borrow_mut() = v;
            }
            Type::Var { typ }
        }
        Type::App {
            public,
            module,
            name,
            args,
        } => {
            let args = args.into_iter().map(|t| generalise(t, ctx_level)).collect();
            Type::App {
                public,
                module,
                name,
                args,
            }
        }
        Type::Fn { args, retrn } => {
            let args = args.into_iter().map(|t| generalise(t, ctx_level)).collect();
            let retrn = generalise(*retrn, ctx_level);
            Type::Fn {
                args,
                retrn: Box::new(retrn),
            }
        }
        Type::Tuple { elems } => Type::Tuple {
            elems: elems
                .into_iter()
                .map(|t| generalise(t, ctx_level))
                .collect(),
        },
    }
}
fn generalise ( t : Type , ctx_level : usize ) -> Type { match t { Type :: Var { typ } => { let new_var = match & * typ . borrow ( ) { TypeVar :: Unbound { id , level } => { let id = * id ; if * level > ctx_level { return Type :: Var { typ : Rc :: new ( RefCell :: new ( TypeVar :: Generic { id } ) ) , } ; } else { Some ( TypeVar :: Unbound { id , level : * level } ) } } TypeVar :: Link { typ } => return generalise ( ( * * typ ) . clone ( ) , ctx_level ) , TypeVar :: Generic { .. } => None , } ; if let Some ( v ) = new_var { * typ . borrow_mut ( ) = v ; } Type :: Var { typ } } Type :: App { public , module , name , args , } => { let args = args . into_iter ( ) . map ( | t | generalise ( t , ctx_level ) ) . collect ( ) ; Type :: App { public , module , name , args , } } Type :: Fn { args , retrn } => { let args = args . into_iter ( ) . map ( | t | generalise ( t , ctx_level ) ) . collect ( ) ; let retrn = generalise ( * retrn , ctx_level ) ; Type :: Fn { args , retrn : Box :: new ( retrn ) , } } Type :: Tuple { elems } => Type :: Tuple { elems : elems . into_iter ( ) . map ( | t | generalise ( t , ctx_level ) ) . collect ( ) , } , } }
Takes a level and a type and turns all type variables within the type that have
level higher than the input level into generalized (polymorphic) type variables.
Takes a level and a type and turns all type variables within the type that have level higher than the input level into generalized ( polymorphic ) type variables .
t
Type
ctx_level
usize
t
Type
ctx_level
usize