ergotree_ir/types/
sfunc.rs

1use std::collections::HashMap;
2
3use super::stype::SType;
4use super::stype_param::STypeParam;
5use super::stype_param::STypeVar;
6
7/// Function signature type
8#[derive(PartialEq, Eq, Debug, Clone)]
9pub struct SFunc {
10    /// Function parameter types
11    pub t_dom: Vec<SType>,
12    /// Result type
13    pub t_range: Box<SType>,
14    /// Type parameters if the function is generic
15    pub tpe_params: Vec<STypeParam>,
16}
17
18impl std::fmt::Display for SFunc {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        write!(f, "(")?;
21        for (i, item) in self.t_dom.iter().enumerate() {
22            if i > 0 {
23                write!(f, ", ")?;
24            }
25            item.fmt(f)?;
26        }
27        write!(f, ") => ")?;
28        self.t_range.fmt(f)
29    }
30}
31
32impl SFunc {
33    /// Create new SFunc
34    pub fn new(t_dom: Vec<SType>, t_range: SType) -> Self {
35        Self {
36            t_dom,
37            t_range: t_range.into(),
38            tpe_params: vec![],
39        }
40    }
41
42    pub(crate) fn with_subst(&self, subst: &HashMap<STypeVar, SType>) -> Self {
43        let remaining_vars = self
44            .tpe_params
45            .iter()
46            .filter(|v| !subst.contains_key(&v.ident))
47            .cloned()
48            .collect();
49        SFunc {
50            t_dom: self
51                .t_dom
52                .iter()
53                .map(|a| a.clone().with_subst(subst))
54                .collect(),
55            t_range: Box::new(self.t_range.with_subst(subst)),
56            tpe_params: remaining_vars,
57        }
58    }
59
60    /// Returns function parameter types (t_dom) with added result type (t_range)
61    pub fn t_dom_plus_range(&self) -> Vec<SType> {
62        let mut res = self.t_dom.clone();
63        res.push(*self.t_range.clone());
64        res
65    }
66}