mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
add unique builtins for AStar
This commit is contained in:
parent
d34c96ec96
commit
c6121e3805
2 changed files with 348 additions and 11 deletions
|
@ -6,7 +6,7 @@ use roc_types::solved_types::{BuiltinAlias, SolvedType};
|
||||||
use roc_types::subs::VarId;
|
use roc_types::subs::VarId;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
Standard,
|
Standard,
|
||||||
Uniqueness,
|
Uniqueness,
|
||||||
|
|
|
@ -25,6 +25,22 @@ const UVAR4: VarId = VarId::from_u32(1004);
|
||||||
const UVAR5: VarId = VarId::from_u32(1005);
|
const UVAR5: VarId = VarId::from_u32(1005);
|
||||||
const UVAR6: VarId = VarId::from_u32(1006);
|
const UVAR6: VarId = VarId::from_u32(1006);
|
||||||
|
|
||||||
|
pub struct IDStore(u32);
|
||||||
|
|
||||||
|
impl IDStore {
|
||||||
|
fn new() -> Self {
|
||||||
|
IDStore(2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fresh(&mut self) -> VarId {
|
||||||
|
let result = VarId::from_u32(self.0);
|
||||||
|
|
||||||
|
self.0 += 1;
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn shared() -> SolvedType {
|
fn shared() -> SolvedType {
|
||||||
SolvedType::Boolean(SolvedAtom::Zero, vec![])
|
SolvedType::Boolean(SolvedAtom::Zero, vec![])
|
||||||
}
|
}
|
||||||
|
@ -207,16 +223,6 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// List a : [ @List a ]
|
|
||||||
add_alias(
|
|
||||||
Symbol::LIST_LIST,
|
|
||||||
BuiltinAlias {
|
|
||||||
region: Region::zero(),
|
|
||||||
vars: vec![Located::at(Region::zero(), "elem".into())],
|
|
||||||
typ: single_private_tag(Symbol::LIST_AT_LIST, vec![flex(TVAR1)]),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Result a e : [ Ok a, Err e ]
|
// Result a e : [ Ok a, Err e ]
|
||||||
add_alias(
|
add_alias(
|
||||||
Symbol::RESULT_RESULT,
|
Symbol::RESULT_RESULT,
|
||||||
|
@ -236,6 +242,39 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// List a : [ @List a ]
|
||||||
|
add_alias(
|
||||||
|
Symbol::LIST_LIST,
|
||||||
|
BuiltinAlias {
|
||||||
|
region: Region::zero(),
|
||||||
|
vars: vec![Located::at(Region::zero(), "elem".into())],
|
||||||
|
typ: single_private_tag(Symbol::LIST_AT_LIST, vec![flex(TVAR1)]),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Map key value : [ @Map key value ]
|
||||||
|
add_alias(
|
||||||
|
Symbol::MAP_MAP,
|
||||||
|
BuiltinAlias {
|
||||||
|
region: Region::zero(),
|
||||||
|
vars: vec![
|
||||||
|
Located::at(Region::zero(), "key".into()),
|
||||||
|
Located::at(Region::zero(), "value".into()),
|
||||||
|
],
|
||||||
|
typ: single_private_tag(Symbol::MAP_AT_MAP, vec![flex(TVAR1), flex(TVAR2)]),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set key : [ @Set key ]
|
||||||
|
add_alias(
|
||||||
|
Symbol::SET_SET,
|
||||||
|
BuiltinAlias {
|
||||||
|
region: Region::zero(),
|
||||||
|
vars: vec![Located::at(Region::zero(), "key".into())],
|
||||||
|
typ: single_private_tag(Symbol::SET_AT_SET, vec![flex(TVAR1)]),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Str : [ @Str ]
|
// Str : [ @Str ]
|
||||||
add_alias(
|
add_alias(
|
||||||
Symbol::STR_STR,
|
Symbol::STR_STR,
|
||||||
|
@ -342,6 +381,12 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// toFloat : Num a -> Float
|
||||||
|
add_type(
|
||||||
|
Symbol::NUM_TO_FLOAT,
|
||||||
|
unique_function(vec![num_type(UVAR1, TVAR1)], float_type(UVAR2)),
|
||||||
|
);
|
||||||
|
|
||||||
// Int module
|
// Int module
|
||||||
|
|
||||||
// highest : Int
|
// highest : Int
|
||||||
|
@ -396,6 +441,18 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
|
|
||||||
// Bool module
|
// Bool module
|
||||||
|
|
||||||
|
// isEq or (==) : Attr u1 Bool, Attr u2 Bool -> Attr u3 Bool
|
||||||
|
add_type(
|
||||||
|
Symbol::BOOL_EQ,
|
||||||
|
unique_function(vec![bool_type(UVAR1), bool_type(UVAR2)], bool_type(UVAR3)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// isNeq or (!=) : Attr u1 Bool, Attr u2 Bool -> Attr u3 Bool
|
||||||
|
add_type(
|
||||||
|
Symbol::BOOL_NEQ,
|
||||||
|
unique_function(vec![bool_type(UVAR1), bool_type(UVAR2)], bool_type(UVAR3)),
|
||||||
|
);
|
||||||
|
|
||||||
// and or (&&) : Attr u1 Bool, Attr u2 Bool -> Attr u3 Bool
|
// and or (&&) : Attr u1 Bool, Attr u2 Bool -> Attr u3 Bool
|
||||||
add_type(
|
add_type(
|
||||||
Symbol::BOOL_AND,
|
Symbol::BOOL_AND,
|
||||||
|
@ -557,6 +614,267 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Map module
|
||||||
|
|
||||||
|
// empty : Map k v
|
||||||
|
add_type(Symbol::MAP_EMPTY, map_type(UVAR1, TVAR1, TVAR2));
|
||||||
|
|
||||||
|
// singleton : k, v -> Map k v
|
||||||
|
add_type(
|
||||||
|
Symbol::MAP_SINGLETON,
|
||||||
|
unique_function(
|
||||||
|
vec![flex(TVAR1), flex(TVAR2)],
|
||||||
|
map_type(UVAR1, TVAR1, TVAR2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// get : Attr (u | v | *) (Map (Attr u key) (Attr v val), (Attr * key) -> Attr * (Result (Attr v val) [ KeyNotFound ]*)
|
||||||
|
let key_not_found = SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
SolvedType::Wildcard,
|
||||||
|
SolvedType::TagUnion(
|
||||||
|
vec![(TagName::Global("KeyNotFound".into()), vec![])],
|
||||||
|
Box::new(SolvedType::Wildcard),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
add_type(Symbol::MAP_GET, {
|
||||||
|
let mut store = IDStore::new();
|
||||||
|
|
||||||
|
let u = store.fresh();
|
||||||
|
let v = store.fresh();
|
||||||
|
let key = store.fresh();
|
||||||
|
let val = store.fresh();
|
||||||
|
let star1 = store.fresh();
|
||||||
|
let star2 = store.fresh();
|
||||||
|
let star3 = store.fresh();
|
||||||
|
|
||||||
|
unique_function(
|
||||||
|
vec![
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star1, vec![u, v]),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::MAP_MAP,
|
||||||
|
vec![attr_type(u, key), attr_type(v, val)],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![disjunction(star2, vec![u]), flex(key)],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
flex(star3),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::RESULT_RESULT,
|
||||||
|
vec![attr_type(v, val), key_not_found],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// insert : Attr (u | v | *) (Map (Attr u key) (Attr v val)), Attr (u | *) key, Attr (v | *) val -> Attr * (Map (Attr u key) (Attr v val))
|
||||||
|
add_type(Symbol::MAP_INSERT, {
|
||||||
|
let mut store = IDStore::new();
|
||||||
|
|
||||||
|
let u = store.fresh();
|
||||||
|
let v = store.fresh();
|
||||||
|
let key = store.fresh();
|
||||||
|
let val = store.fresh();
|
||||||
|
let star1 = store.fresh();
|
||||||
|
let star2 = store.fresh();
|
||||||
|
let star3 = store.fresh();
|
||||||
|
|
||||||
|
unique_function(
|
||||||
|
vec![
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star1, vec![u, v]),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::MAP_MAP,
|
||||||
|
vec![attr_type(u, key), attr_type(v, val)],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![disjunction(star2, vec![u]), flex(key)],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![disjunction(star2, vec![v]), flex(val)],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
flex(star3),
|
||||||
|
SolvedType::Apply(Symbol::MAP_MAP, vec![attr_type(u, key), attr_type(v, val)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set module
|
||||||
|
|
||||||
|
// empty : Set a
|
||||||
|
add_type(Symbol::SET_EMPTY, set_type(UVAR1, TVAR1));
|
||||||
|
|
||||||
|
// singleton : a -> Set a
|
||||||
|
add_type(
|
||||||
|
Symbol::SET_SINGLETON,
|
||||||
|
unique_function(vec![flex(TVAR1)], set_type(UVAR1, TVAR1)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// op : Attr (u | *) (Set (Attr u a)), Attr (u | *) (Set (Attr u a)) -> Attr * Set (Attr u a)
|
||||||
|
let set_combine = {
|
||||||
|
let mut store = IDStore::new();
|
||||||
|
|
||||||
|
let u = store.fresh();
|
||||||
|
let a = store.fresh();
|
||||||
|
let star1 = store.fresh();
|
||||||
|
let star2 = store.fresh();
|
||||||
|
let star3 = store.fresh();
|
||||||
|
|
||||||
|
unique_function(
|
||||||
|
vec![
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star1, vec![u]),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star2, vec![u]),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
flex(star3),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// union : Set a, Set a -> Set a
|
||||||
|
add_type(Symbol::SET_UNION, set_combine.clone());
|
||||||
|
|
||||||
|
// diff : Set a, Set a -> Set a
|
||||||
|
add_type(Symbol::SET_DIFF, set_combine);
|
||||||
|
|
||||||
|
// foldl : Attr (u | *) (Set (Attr u a)), Attr Shared (Attr u a -> b -> b), b -> b
|
||||||
|
add_type(Symbol::SET_FOLDL, {
|
||||||
|
let mut store = IDStore::new();
|
||||||
|
|
||||||
|
let u = store.fresh();
|
||||||
|
let a = store.fresh();
|
||||||
|
let b = store.fresh();
|
||||||
|
let star1 = store.fresh();
|
||||||
|
|
||||||
|
unique_function(
|
||||||
|
vec![
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star1, vec![u]),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
shared(),
|
||||||
|
SolvedType::Func(vec![attr_type(u, a), flex(b)], Box::new(flex(b))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
flex(b),
|
||||||
|
],
|
||||||
|
flex(b),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// insert : Attr (u | *) (Set (Attr u a)), Attr (u | *) a -> Attr * (Set (Attr u a))
|
||||||
|
add_type(Symbol::SET_INSERT, {
|
||||||
|
let mut store = IDStore::new();
|
||||||
|
|
||||||
|
let u = store.fresh();
|
||||||
|
let a = store.fresh();
|
||||||
|
let star1 = store.fresh();
|
||||||
|
let star2 = store.fresh();
|
||||||
|
let star3 = store.fresh();
|
||||||
|
|
||||||
|
unique_function(
|
||||||
|
vec![
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star1, vec![u]),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![disjunction(star2, vec![u]), flex(a)],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
flex(star3),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// we can remove a key that is shared from a set of unique keys
|
||||||
|
// remove : Attr (u | *) (Set (Attr u a)), Attr * a -> Attr * (Set (Attr u a))
|
||||||
|
add_type(Symbol::SET_REMOVE, {
|
||||||
|
let mut store = IDStore::new();
|
||||||
|
|
||||||
|
let u = store.fresh();
|
||||||
|
let a = store.fresh();
|
||||||
|
let star1 = store.fresh();
|
||||||
|
let star2 = store.fresh();
|
||||||
|
let star3 = store.fresh();
|
||||||
|
|
||||||
|
unique_function(
|
||||||
|
vec![
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
disjunction(star1, vec![u]),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SolvedType::Apply(Symbol::ATTR_ATTR, vec![flex(star2), flex(a)]),
|
||||||
|
],
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
flex(star3),
|
||||||
|
SolvedType::Apply(Symbol::SET_SET, vec![attr_type(u, a)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
// Str module
|
// Str module
|
||||||
|
|
||||||
// isEmpty : Attr u Str -> Attr v Bool
|
// isEmpty : Attr u Str -> Attr v Bool
|
||||||
|
@ -688,3 +1006,22 @@ fn list_type(u: VarId, a: VarId) -> SolvedType {
|
||||||
vec![flex(u), SolvedType::Apply(Symbol::LIST_LIST, vec![flex(a)])],
|
vec![flex(u), SolvedType::Apply(Symbol::LIST_LIST, vec![flex(a)])],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn set_type(u: VarId, a: VarId) -> SolvedType {
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![flex(u), SolvedType::Apply(Symbol::SET_SET, vec![flex(a)])],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn map_type(u: VarId, key: VarId, value: VarId) -> SolvedType {
|
||||||
|
SolvedType::Apply(
|
||||||
|
Symbol::ATTR_ATTR,
|
||||||
|
vec![
|
||||||
|
flex(u),
|
||||||
|
SolvedType::Apply(Symbol::MAP_MAP, vec![flex(key), flex(value)]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue