add curry/decurry

This commit is contained in:
Michael Sippel 2023-10-02 01:45:54 +02:00
parent 3fc691acf2
commit 2d3b234e6e
Signed by: senvas
GPG key ID: F96CF119C34B64A6
3 changed files with 117 additions and 1 deletions

63
src/curry.rs Normal file
View 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
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\

View file

@ -4,6 +4,7 @@ pub mod dict;
pub mod term;
pub mod lexer;
pub mod parser;
pub mod curry;
#[cfg(test)]
mod test;

View file

@ -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()
);
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\