pub fn type_from_ast(
        &mut self,
        ast: &TypeAst,
        vars: &mut im::HashMap<String, (usize, Type)>,
        new: NewTypeAction,
    ) -> Result<Type, Error> {
        match ast {
            TypeAst::Constructor {
                meta,
                module,
                name,
                args,
            } => {
                let args = args
                    .iter()
                    .map(|t| self.type_from_ast(t, vars, new))
                    .collect::<Result<Vec<_>, _>>()?;
                let info = self
                    .get_type_constructor(module, name)
                    .map_err(|e| convert_get_type_constructor_error(e, &meta))?;
                if args.len() != info.arity {
                    return Err(Error::IncorrectTypeArity {
                        meta: meta.clone(),
                        name: name.to_string(),
                        expected: info.arity,
                        given: args.len(),
                    });
                }
                Ok(Type::App {
                    name: name.to_string(),
                    module: info.module.clone(),
                    public: info.public,
                    args,
                })
            }

            TypeAst::Tuple { elems, .. } => {
                let elems = elems
                    .iter()
                    .map(|t| self.type_from_ast(t, vars, new))
                    .collect::<Result<_, _>>()?;
                Ok(Type::Tuple { elems })
            }

            TypeAst::Fn { args, retrn, .. } => {
                let args = args
                    .iter()
                    .map(|t| self.type_from_ast(t, vars, new))
                    .collect::<Result<_, _>>()?;
                let retrn = self.type_from_ast(retrn, vars, new)?;
                Ok(Type::Fn {
                    args,
                    retrn: Box::new(retrn),
                })
            }

            TypeAst::Var { name, meta, .. } => match vars.get(name) {
                Some((_, var)) => Ok(var.clone()),

                None => match new {
                    NewTypeAction::MakeGeneric => {
                        let var = self.new_generic_var();
                        vars.insert(name.to_string(), (self.previous_uid(), var.clone()));
                        Ok(var)
                    }
                    NewTypeAction::Disallow => Err(Error::UnknownType {
                        name: name.to_string(),
                        meta: meta.clone(),
                        types: self.module_types.clone(),
                    }),
                },
            },
        }
    }
/// Construct a Type from an AST Type annotation.
///
/// Type variables are managed using a HashMap of names to types- this permits the
/// same type vars being shared between multiple annotations (such as in the arguments
/// of an external function declaration)
///
Construct a Type from an AST Type annotation.
Type variables are managed using a HashMap of names to types- this permits the
same type vars being shared between multiple annotations (such as in the arguments
of an external function declaration)
Construct a Type from an AST Type annotation . Type variables are managed using a HashMap of names to types - this permits the same type vars being shared between multiple annotations ( such as in the arguments of an external function declaration )
pub fn type_from_ast(
        &mut self,
        ast: &TypeAst,
        vars: &mut im::HashMap<String, (usize, Type)>,
        new: NewTypeAction,
    ) -> Result<Type, Error> {
        match ast {
            TypeAst::Constructor {
                meta,
                module,
                name,
                args,
            } => {
                let args = args
                    .iter()
                    .map(|t| self.type_from_ast(t, vars, new))
                    .collect::<Result<Vec<_>, _>>()?;
                let info = self
                    .get_type_constructor(module, name)
                    .map_err(|e| convert_get_type_constructor_error(e, &meta))?;
                if args.len() != info.arity {
                    return Err(Error::IncorrectTypeArity {
                        meta: meta.clone(),
                        name: name.to_string(),
                        expected: info.arity,
                        given: args.len(),
                    });
                }
                Ok(Type::App {
                    name: name.to_string(),
                    module: info.module.clone(),
                    public: info.public,
                    args,
                })
            }
            TypeAst::Tuple { elems, .. } => {
                let elems = elems
                    .iter()
                    .map(|t| self.type_from_ast(t, vars, new))
                    .collect::<Result<_, _>>()?;
                Ok(Type::Tuple { elems })
            }
            TypeAst::Fn { args, retrn, .. } => {
                let args = args
                    .iter()
                    .map(|t| self.type_from_ast(t, vars, new))
                    .collect::<Result<_, _>>()?;
                let retrn = self.type_from_ast(retrn, vars, new)?;
                Ok(Type::Fn {
                    args,
                    retrn: Box::new(retrn),
                })
            }
            TypeAst::Var { name, meta, .. } => match vars.get(name) {
                Some((_, var)) => Ok(var.clone()),
                None => match new {
                    NewTypeAction::MakeGeneric => {
                        let var = self.new_generic_var();
                        vars.insert(name.to_string(), (self.previous_uid(), var.clone()));
                        Ok(var)
                    }
                    NewTypeAction::Disallow => Err(Error::UnknownType {
                        name: name.to_string(),
                        meta: meta.clone(),
                        types: self.module_types.clone(),
                    }),
                },
            },
        }
    }
pub fn type_from_ast ( & mut self , ast : & TypeAst , vars : & mut im :: HashMap < String , ( usize , Type ) > , new : NewTypeAction , ) -> Result < Type , Error > { match ast { TypeAst :: Constructor { meta , module , name , args , } => { let args = args . iter ( ) . map ( | t | self . type_from_ast ( t , vars , new ) ) . collect :: < Result < Vec < _ > , _ > > ( ) ? ; let info = self . get_type_constructor ( module , name ) . map_err ( | e | convert_get_type_constructor_error ( e , & meta ) ) ? ; if args . len ( ) != info . arity { return Err ( Error :: IncorrectTypeArity { meta : meta . clone ( ) , name : name . to_string ( ) , expected : info . arity , given : args . len ( ) , } ) ; } Ok ( Type :: App { name : name . to_string ( ) , module : info . module . clone ( ) , public : info . public , args , } ) } TypeAst :: Tuple { elems , .. } => { let elems = elems . iter ( ) . map ( | t | self . type_from_ast ( t , vars , new ) ) . collect :: < Result < _ , _ > > ( ) ? ; Ok ( Type :: Tuple { elems } ) } TypeAst :: Fn { args , retrn , .. } => { let args = args . iter ( ) . map ( | t | self . type_from_ast ( t , vars , new ) ) . collect :: < Result < _ , _ > > ( ) ? ; let retrn = self . type_from_ast ( retrn , vars , new ) ? ; Ok ( Type :: Fn { args , retrn : Box :: new ( retrn ) , } ) } TypeAst :: Var { name , meta , .. } => match vars . get ( name ) { Some ( ( _ , var ) ) => Ok ( var . clone ( ) ) , None => match new { NewTypeAction :: MakeGeneric => { let var = self . new_generic_var ( ) ; vars . insert ( name . to_string ( ) , ( self . previous_uid ( ) , var . clone ( ) ) ) ; Ok ( var ) } NewTypeAction :: Disallow => Err ( Error :: UnknownType { name : name . to_string ( ) , meta : meta . clone ( ) , types : self . module_types . clone ( ) , } ) , } , } , } }
Construct a Type from an AST Type annotation.
Construct a Type from an AST Type annotation .
&mut self
ast
&TypeAst
vars
&mut im::HashMap<String, (usize, Type)>
new
NewTypeAction
&mut self
ast
&TypeAst
vars
&mut im::HashMap<String, (usize, Type)>
new
NewTypeAction