-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into nd60/new-solver-interface
- Loading branch information
Showing
8 changed files
with
402 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "uniplate" | ||
version = "0.1.0" | ||
edition = "2021" | ||
description="Boilerplate-free generic operations on data, Haskell style." | ||
license = "MPL-2.0" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
|
||
[lints] | ||
workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
//! A port of Haskell's [Uniplate](https://hackage.haskell.org/package/uniplate) in Rust. | ||
//! | ||
//! | ||
//! # Examples | ||
//! | ||
//! ## A Calculator Input Language | ||
//! | ||
//! Consider the AST of a calculator input language: | ||
//! | ||
//! ``` | ||
//! pub enum AST { | ||
//! Int(i32), | ||
//! Add(Box<AST>,Box<AST>), | ||
//! Sub(Box<AST>,Box<AST>), | ||
//! Div(Box<AST>,Box<AST>), | ||
//! Mul(Box<AST>,Box<AST>) | ||
//! } | ||
//!``` | ||
//! | ||
//! Using uniplate, one can implement a single function for this AST that can be used in a whole | ||
//! range of traversals. | ||
//! | ||
//! While this does not seem helpful in this toy example, the benefits amplify when the number of | ||
//! enum variants increase, and the different types contained in their fields increase. | ||
//! | ||
//! | ||
//! The below example implements [`Uniplate`](uniplate::Uniplate) for this language AST, and uses uniplate methods to | ||
//! evaluate the encoded equation. | ||
//! | ||
//!``` | ||
//! use uniplate::uniplate::Uniplate; | ||
//! | ||
//! #[derive(Clone,Eq,PartialEq,Debug)] | ||
//! pub enum AST { | ||
//! Int(i32), | ||
//! Add(Box<AST>,Box<AST>), | ||
//! Sub(Box<AST>,Box<AST>), | ||
//! Div(Box<AST>,Box<AST>), | ||
//! Mul(Box<AST>,Box<AST>) | ||
//! } | ||
//! | ||
//! // In the future would be automatically derived. | ||
//! impl Uniplate for AST { | ||
//! fn uniplate(&self) -> (Vec<AST>, Box<dyn Fn(Vec<AST>) -> AST +'_>) { | ||
//! let context: Box<dyn Fn(Vec<AST>) -> AST> = match self { | ||
//! AST::Int(i) => Box::new(|_| AST::Int(*i)), | ||
//! AST::Add(_, _) => Box::new(|exprs: Vec<AST>| AST::Add(Box::new(exprs[0].clone()),Box::new(exprs[1].clone()))), | ||
//! AST::Sub(_, _) => Box::new(|exprs: Vec<AST>| AST::Sub(Box::new(exprs[0].clone()),Box::new(exprs[1].clone()))), | ||
//! AST::Div(_, _) => Box::new(|exprs: Vec<AST>| AST::Div(Box::new(exprs[0].clone()),Box::new(exprs[1].clone()))), | ||
//! AST::Mul(_, _) => Box::new(|exprs: Vec<AST>| AST::Mul(Box::new(exprs[0].clone()),Box::new(exprs[1].clone()))) | ||
//! }; | ||
//! | ||
//! let children: Vec<AST> = match self { | ||
//! AST::Add(a,b) => vec![*a.clone(),*b.clone()], | ||
//! AST::Sub(a,b) => vec![*a.clone(),*b.clone()], | ||
//! AST::Div(a,b) => vec![*a.clone(),*b.clone()], | ||
//! AST::Mul(a,b) => vec![*a.clone(),*b.clone()], | ||
//! _ => vec![] | ||
//! }; | ||
//! | ||
//! (children,context) | ||
//! } | ||
//! } | ||
//! | ||
//! pub fn my_rule(e: AST) -> AST{ | ||
//! match e { | ||
//! AST::Int(a) => AST::Int(a), | ||
//! AST::Add(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a+b), _ => AST::Add(a,b) }}, | ||
//! AST::Sub(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a-b), _ => AST::Sub(a,b) }}, | ||
//! AST::Mul(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a*b), _ => AST::Mul(a,b) }}, | ||
//! AST::Div(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a/b), _ => AST::Div(a,b) }} | ||
//! } | ||
//! } | ||
//! pub fn main() { | ||
//! let mut ast = AST::Add( | ||
//! Box::new(AST::Int(1)), | ||
//! Box::new(AST::Mul( | ||
//! Box::new(AST::Int(2)), | ||
//! Box::new(AST::Div( | ||
//! Box::new(AST::Add(Box::new(AST::Int(1)),Box::new(AST::Int(2)))), | ||
//! Box::new(AST::Int(3)) | ||
//! ))))); | ||
//! | ||
//! ast = ast.transform(my_rule); | ||
//! println!("{:?}",ast); | ||
//! assert_eq!(ast,AST::Int(3)); | ||
//! } | ||
//! ``` | ||
//! | ||
//! ....MORE DOCS TO COME.... | ||
//! | ||
//! # Acknowledgements / Related Work | ||
//! | ||
//! *This crate implements programming constructs from the following Haskell libraries and | ||
//! papers:* | ||
//! | ||
//! * [Uniplate](https://hackage.haskell.org/package/uniplate). | ||
//! | ||
//! * Neil Mitchell and Colin Runciman. 2007. Uniform boilerplate and list processing. In | ||
//! Proceedings of the ACM SIGPLAN workshop on Haskell workshop (Haskell '07). Association for | ||
//! Computing Machinery, New York, NY, USA, 49–60. <https://doi.org/10.1145/1291201.1291208> | ||
//! [(free copy)](https://www.cs.york.ac.uk/plasma/publications/pdf/MitchellRuncimanHW07.pdf) | ||
//! | ||
//! * Huet G. The Zipper. Journal of Functional Programming. 1997;7(5):549–54. <https://doi.org/10.1017/S0956796897002864> | ||
//! [(free copy)](https://www.cambridge.org/core/services/aop-cambridge-core/content/view/0C058890B8A9B588F26E6D68CF0CE204/S0956796897002864a.pdf/zipper.pdf) | ||
|
||
//! | ||
|
||
pub mod uniplate; |
Oops, something went wrong.