add curry/decurry
This commit is contained in:
parent
3fc691acf2
commit
2d3b234e6e
3 changed files with 117 additions and 1 deletions
63
src/curry.rs
Normal file
63
src/curry.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use crate::term::*;
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
impl TypeTerm {
|
||||
/// transform term to have at max 2 entries in Application list
|
||||
pub fn curry(mut self) -> TypeTerm {
|
||||
match self {
|
||||
TypeTerm::App(args) => {
|
||||
if args.len() >= 2 {
|
||||
let mut old_args = args.into_iter();
|
||||
let mut new_args = vec![
|
||||
old_args.next().unwrap(),
|
||||
old_args.next().unwrap()
|
||||
];
|
||||
|
||||
for x in old_args {
|
||||
new_args = vec![
|
||||
TypeTerm::App(new_args),
|
||||
x
|
||||
];
|
||||
}
|
||||
|
||||
TypeTerm::App(new_args)
|
||||
} else {
|
||||
TypeTerm::App(args)
|
||||
}
|
||||
}
|
||||
|
||||
TypeTerm::Ladder(rungs) => {
|
||||
TypeTerm::Ladder(rungs.into_iter().map(|r| r.curry()).collect())
|
||||
}
|
||||
|
||||
_ => self
|
||||
}
|
||||
}
|
||||
|
||||
/// summarize all curried applications into one vec
|
||||
pub fn decurry(mut self) -> Self {
|
||||
match self {
|
||||
TypeTerm::App(mut args) => {
|
||||
if args.len() > 0 {
|
||||
let mut a0 = args.remove(0).decurry();
|
||||
match a0 {
|
||||
TypeTerm::App(sub_args) => {
|
||||
for (i,x) in sub_args.into_iter().enumerate() {
|
||||
args.insert(i, x);
|
||||
}
|
||||
}
|
||||
other => { args.insert(0, other); }
|
||||
}
|
||||
}
|
||||
TypeTerm::App(args)
|
||||
}
|
||||
TypeTerm::Ladder(args) => {
|
||||
TypeTerm::Ladder(args.into_iter().map(|a| a.decurry()).collect())
|
||||
}
|
||||
_ => self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
|
@ -4,6 +4,7 @@ pub mod dict;
|
|||
pub mod term;
|
||||
pub mod lexer;
|
||||
pub mod parser;
|
||||
pub mod curry;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
|
|
@ -1,6 +1,58 @@
|
|||
use {
|
||||
crate::{term::*, dict::*, parser::*},
|
||||
std::str::FromStr
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
#[test]
|
||||
fn test_curry() {
|
||||
// todo
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<A B C>").unwrap().curry(),
|
||||
TypeTerm::from_str("<<A B> C>").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<A B C D>").unwrap().curry(),
|
||||
TypeTerm::from_str("<<<A B> C> D>").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<A B C D E F G H I J K>").unwrap().curry(),
|
||||
TypeTerm::from_str("<<<<<<<<<<A B> C> D> E> F> G> H> I> J> K>").unwrap()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<A~X B C>").unwrap().curry(),
|
||||
TypeTerm::from_str("<<A~X B> C>").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<A B C~Y~Z> ~ K").unwrap().curry(),
|
||||
TypeTerm::from_str("< <A B> C~Y~Z > ~ K").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decurry() {
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<<A B> C>").unwrap().decurry(),
|
||||
TypeTerm::from_str("<A B C>").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<<<A B> C> D>").unwrap().decurry(),
|
||||
TypeTerm::from_str("<A B C D>").unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<<<<<<<<<<A B> C> D> E> F> G> H> I> J> K>").unwrap().decurry(),
|
||||
TypeTerm::from_str("<A B C D E F G H I J K>").unwrap()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<<A~X B> C>").unwrap().decurry(),
|
||||
TypeTerm::from_str("<A~X B C>").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TypeTerm::from_str("<<A~X B> C~Y>~K").unwrap().decurry(),
|
||||
TypeTerm::from_str("<A~X B C~Y> ~K").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
|
Loading…
Reference in a new issue