Repository: gluon-lang/gluon
Pull request #732 (2019-05-17 20:46:54)

fix(check): Propagate metadata through parens 
bors r+


Patch:
diff --git a/README.md b/README.md
index 54702012..3959a2a3 100644
--- a/README.md
+++ b/README.md
@@ -218,14 +218,6 @@ guess_loop ()
 
 You can try gluon in your browser at http://gluon-lang.org/try/. ([Github](https://github.com/gluon-lang/try_gluon))
 
-### Install
-
-Gluon can be installed by using one of the prebuilt executables at [Github](https://github.com/gluon-lang/gluon/releases) or you can use Cargo in order to install the `gluon_repl` crate:
-
-```
-cargo install gluon_repl
-```
-
 ### REPL
 
 Gluon has a small executable which can be used to run gluon programs directly or in a small REPL. The REPL can be started by passing the `-i` flag to the built repl executable which can be run with `cargo run -p gluon_repl -- -i`.
diff --git a/base/src/serialization.rs b/base/src/serialization.rs
index 2bb71d7e..d3a381fd 100644
--- a/base/src/serialization.rs
+++ b/base/src/serialization.rs
@@ -85,7 +85,6 @@ where
         + ::std::any::Any
         + DeserializeState<'de, Seed<Id, T>>,
 {
-    use crate::serialization::SharedSeed;
     let seed = SharedSeed::new(seed);
     DeserializeSeed::deserialize(seed, deserializer).map(|vec: Vec<_>| Arc::from(vec))
 }
diff --git a/base/src/symbol.rs b/base/src/symbol.rs
index 05b72c4e..a41e7ca9 100644
--- a/base/src/symbol.rs
+++ b/base/src/symbol.rs
@@ -250,7 +250,6 @@ impl SymbolRef {
 #[cfg_attr(feature = "serde_derive", serde(de_parameters = "S"))]
 pub struct NameBuf(String);
 
-#[allow(derive_hash_xor_eq)]
 #[derive(Debug, Eq, Hash, Ord, PartialOrd)]
 pub struct Name(str);
 
diff --git a/build.rs b/build.rs
index c33c0be9..8d101364 100644
--- a/build.rs
+++ b/build.rs
@@ -107,10 +107,12 @@ mod gen_skeptic {
 
 /// Safety check to make sure that all .rs files in `tests/` will run
 fn check_test_declarations_in_cargo_file() {
-    use std::collections::HashSet;
-    use std::ffi::OsStr;
-    use std::fs::{read_dir, File};
-    use std::io::{BufRead, BufReader};
+    use std::{
+        collections::HashSet,
+        ffi::OsStr,
+        fs::read_dir,
+        io::{BufRead, BufReader},
+    };
 
     let cargo_file = BufReader::new(File::open("Cargo.toml").unwrap());
 
diff --git a/check/src/metadata.rs b/check/src/metadata.rs
index d0595528..f4593cb3 100644
--- a/check/src/metadata.rs
+++ b/check/src/metadata.rs
@@ -65,7 +65,7 @@ impl ArcMetadata for MaybeMetadata {
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 enum MaybeMetadata {
     Empty,
     Data(Arc<Metadata>),
@@ -371,6 +371,7 @@ pub fn metadata(
                 Expr::MacroExpansion {
                     ref replacement, ..
                 } => self.metadata_expr(replacement),
+                Expr::Tuple { ref elems, .. } if elems.len() == 1 => self.metadata_expr(&elems[0]),
                 _ => {
                     ast::walk_expr(self, expr);
                     Default::default()
diff --git a/check/src/typecheck/error.rs b/check/src/typecheck/error.rs
index 03a66d29..9c41ef39 100644
--- a/check/src/typecheck/error.rs
+++ b/check/src/typecheck/error.rs
@@ -92,7 +92,7 @@ where
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use self::TypeError::*;
-        use pretty::{Arena, DocAllocator};
+        use pretty::DocAllocator;
         match &*self {
             UndefinedVariable(name) => write!(f, "Undefined variable `{}`", name),
             NotAFunction(typ) => write!(f, "`{}` is not a function", typ),
diff --git a/parser/src/infix.rs b/parser/src/infix.rs
index 607e06ba..395d6899 100644
--- a/parser/src/infix.rs
+++ b/parser/src/infix.rs
@@ -316,7 +316,6 @@ where
     Id: Eq + Hash + AsRef<str> + ::std::fmt::Debug,
 {
     use self::Error::*;
-    use crate::base::pos;
 
     let make_op = |lhs: Box<SpannedExpr<Id>>, op, rhs: Box<SpannedExpr<Id>>| {
         let span = pos::span(lhs.span.start(), rhs.span.end());
diff --git a/src/std_lib/env.rs b/src/std_lib/env.rs
index f3ff8381..6be99505 100644
--- a/src/std_lib/env.rs
+++ b/src/std_lib/env.rs
@@ -68,8 +68,6 @@ mod std {
 }
 
 pub fn load(vm: &Thread) -> vm::Result<ExternModule> {
-    use self::std;
-
     ExternModule::new(
         vm,
         record! {
diff --git a/src/std_lib/io.rs b/src/std_lib/io.rs
index 79aeac18..c08c94da 100644
--- a/src/std_lib/io.rs
+++ b/src/std_lib/io.rs
@@ -354,8 +354,6 @@ pub fn load(vm: &Thread) -> Result<ExternModule> {
 
     let wrap = vec![Pop(1)];
 
-    use self::std;
-
     // IO functions
     ExternModule::new(
         vm,
diff --git a/src/std_lib/random.rs b/src/std_lib/random.rs
index 57bd8787..b5ce8aff 100644
--- a/src/std_lib/random.rs
+++ b/src/std_lib/random.rs
@@ -63,8 +63,6 @@ mod std {
 }
 
 pub fn load(vm: &Thread) -> vm::Result<ExternModule> {
-    use self::std;
-
     vm.register_type::<XorShiftRng>("std.random.XorShiftRng", &[])?;
 
     ExternModule::new(
diff --git a/src/std_lib/regex.rs b/src/std_lib/regex.rs
index 3cc91a7d..1e2d1cab 100644
--- a/src/std_lib/regex.rs
+++ b/src/std_lib/regex.rs
@@ -74,8 +74,6 @@ mod std {
 }
 
 pub fn load(vm: &Thread) -> vm::Result<ExternModule> {
-    use self::std;
-
     vm.register_type::<Regex>("std.regex.Regex", &[])?;
     vm.register_type::<Error>("std.regex.Error", &[])?;
 
diff --git a/std/lazyt.glu b/std/lazyt.glu
deleted file mode 100644
index 3420655f..00000000
--- a/std/lazyt.glu
+++ /dev/null
@@ -1,44 +0,0 @@
-//@NO-IMPLICIT-PRELUDE
-
-let { Applicative, apply, wrap } = import! std.applicative
-let { (<<) } = import! std.function
-let { Functor, map } = import! std.functor
-let { Lazy, lazy, force } = import! std.lazy
-let { Monad, flat_map } = import! std.monad
-let { Transformer } = import! std.transformer
-
-type LazyT m a = Lazy (m a)
-
-let functor : [Functor m] -> Functor (LazyT m) =
-    let ltmap f ma = lazy (\_ -> map f (force ma))
-
-    { map = ltmap }
-
-let applicative : [Applicative m] -> Applicative (LazyT m) =
-    let ltwrap a = lazy (\_ -> wrap a)
-    let ltapply mf ma = lazy (\_ -> apply (force mf) (force ma))
-
-    { functor, apply = ltapply, wrap = ltwrap }
-
-let monad : [Monad m] -> Monad (LazyT m) =
-    let ltflat_map f ma = lazy (\_ -> flat_map (force << f) (force ma))
-
-    { applicative, flat_map = ltflat_map }
-
-let transformer : Transformer LazyT =
-    let wrap_monad ma : [Monad m] -> m a -> LazyT m a = lazy (\_ -> ma)
-
-    { /* monad, */ wrap_monad }
-
-let force_t : LazyT m a -> m a = force
-
-{
-    LazyT,
-
-    force_t,
-
-    functor,
-    applicative,
-    monad,
-    transformer
-}
diff --git a/std/statet.glu b/std/statet.glu
deleted file mode 100644
index 8f8a0f4b..00000000
--- a/std/statet.glu
+++ /dev/null
@@ -1,93 +0,0 @@
-//! The state monad transformer.
-
-let { Alternative, or, empty } = import! std.alternative
-let { Applicative, wrap, (<*>) } = import! std.applicative
-let { (>>), (<<), ? } = import! std.function
-let { Functor, map } = import! std.functor
-let { Monad, (>>=) } = import! std.monad
-let { Transformer } = import! std.transformer
-
-type StateOut s a = { value : a, state : s }
-type WrStateOut s m a = m { value : a, state : s }
-
-type StateT s m a = s -> m { value : a, state : s }
-
-let map_sout f st : (a -> b) -> StateOut s a -> StateOut s b =
-    {value = f st.value, state = st.state}
-
-let functor : [Functor m] -> Functor (StateT s m) =
-    let stmap f sr : (a -> b) -> StateT s m a -> StateT s m b =
-        map (map_sout f) << sr
-
-    { map = stmap }
-
-// the typechecker can't find map and Functor m without help
-let applicative ?mo : [Monad m] -> Applicative (StateT s m) =
-    let apply srf sr : StateT s m (a -> b) -> StateT s m a -> StateT s m b = \state ->
-        srf state >>= \fout ->
-            let {value = f, state = state'} = fout
-            mo.applicative.functor.map (map_sout f) (sr state')
-
-    let stwrap value : a -> StateT s m a = \state ->
-        wrap { value, state }
-
-    { functor = functor ?mo.applicative.functor, apply, wrap = stwrap }
-
-let monad : [Monad m] -> Monad (StateT s m) =
-    let flat_map f sr : (a -> StateT s m b) -> StateT s m a -> StateT s m b = \state ->
-        sr state >>= \sout ->
-            let {value, state = state'} = sout
-            f value state'
-
-    { applicative, flat_map }
-
-let transformer : Transformer (StateT s) =
-    let wrap_monad ma : [Monad m] -> m a -> StateT s m a = \state ->
-        ma >>= \value -> wrap {value, state}
-
-    { /* monad, */ wrap_monad }
-
-let alternative : [Monad m] -> [Alternative m] -> Alternative (StateT s m) =
-    let stor sra srb = or << sra <*> srb
-    let stempty = transformer.wrap_monad empty
-
-    { applicative, or = stor, empty = stempty }
-
-let put value : [Monad m] -> s -> StateT s m () = \state ->
-    wrap { value = (), state = value }
-
-let get : [Monad m] -> StateT s m s = \state ->
-    wrap { value = state, state }
-
-let gets f : [Monad m] -> (s -> a) -> StateT s m a =
-    get >>= (wrap << f)
-
-let modify f : [Monad m] -> (s -> s) -> StateT s m () =
-    get >>= (put << f)
-
-let run_state_t f state : StateT s m a -> s -> m { value : a, state : s } =
-    f state
-
-let eval_state_t f state : [Functor m] -> StateT s m a -> s -> m a =
-    map (\x -> x.value) (run_state_t f state)
-
-let exec_state_t f state : [Functor m] -> StateT s m a -> s -> m s =
-    map (\x -> x.state) (run_state_t f state)
-
-{
-    StateT,
-
-    applicative,
-    functor,
-    monad,
-    transformer,
-    alternative,
-
-    put,
-    get,
-    gets,
-    modify,
-    run_state_t,
-    eval_state_t,
-    exec_state_t
-}
diff --git a/std/transformer.glu b/std/transformer.glu
deleted file mode 100644
index 0425f6ff..00000000
--- a/std/transformer.glu
+++ /dev/null
@@ -1,14 +0,0 @@
-//@NO-IMPLICIT-PRELUDE
-
-let { Monad } = import! std.prelude
-
-#[implicit]
-type Transformer t = {
-/*     monad : forall m . [Monad m] -> Monad (t m), */
-    wrap_monad : forall a m . [Monad m] -> m a -> t m a
-}
-
-let wrap_monad ?_ ?tr ma : [Monad m] -> [Transformer t] -> m a -> t m a =
-    tr.wrap_monad ma
-
-{ Transformer, wrap_monad }
diff --git a/vm/src/core/mod.rs b/vm/src/core/mod.rs
index e3fbc374..a389b4b5 100644
--- a/vm/src/core/mod.rs
+++ b/vm/src/core/mod.rs
@@ -1153,8 +1153,6 @@ impl<'a, 'e> PatternTranslator<'a, 'e> {
         variables: &[&'a Expr<'a>],
         equations: &[Equation<'a, 'p>],
     ) -> &'a Expr<'a> {
-        use std::borrow::Cow;
-
         let new_alt = {
             // Inspect the first pattern of each equation
             // (the rest of the equations are checked recursively)
diff --git a/vm/src/debug.rs b/vm/src/debug.rs
index 0a6a8c78..e32778c4 100644
--- a/vm/src/debug.rs
+++ b/vm/src/debug.rs
@@ -27,8 +27,6 @@ mod std {
 }
 
 pub fn load(vm: &Thread) -> Result<ExternModule> {
-    use self::std;
-
     ExternModule::new(
         vm,
         record! {
diff --git a/vm/src/lazy.rs b/vm/src/lazy.rs
index 7ed3e6d9..d2d7f8ad 100644
--- a/vm/src/lazy.rs
+++ b/vm/src/lazy.rs
@@ -194,8 +194,6 @@ mod std {
 }
 
 pub fn load(vm: &Thread) -> Result<ExternModule> {
-    use self::std;
-
     ExternModule::new(
         vm,
         record! {
diff --git a/vm/src/primitives.rs b/vm/src/primitives.rs
index 6acde751..b0e12ea9 100644
--- a/vm/src/primitives.rs
+++ b/vm/src/primitives.rs
@@ -198,7 +198,6 @@ mod string {
                 size_of::<ValueArray>() + (self.lhs.len() + self.rhs.len()) * size_of::<u8>()
             }
             fn initialize<'w>(self, mut result: WriteOnly<'w, ValueArray>) -> &'w mut ValueArray {
-                use crate::value::Repr;
                 unsafe {
                     let result = &mut *result.as_mut_ptr();
                     result.set_repr(Repr::Byte);
@@ -371,7 +370,6 @@ mod std {
 
 #[allow(non_camel_case_types)]
 pub fn load_float(thread: &Thread) -> Result<ExternModule> {
-    use self::std;
     use crate::real_std::f64;
 
     ExternModule::new(
@@ -444,7 +442,6 @@ pub fn load_float(thread: &Thread) -> Result<ExternModule> {
 
 #[allow(non_camel_case_types)]
 pub fn load_byte(vm: &Thread) -> Result<ExternModule> {
-    use self::std;
     ExternModule::new(
         vm,
         record! {
@@ -481,7 +478,6 @@ pub fn load_byte(vm: &Thread) -> Result<ExternModule> {
 
 #[allow(non_camel_case_types)]
 pub fn load_int(vm: &Thread) -> Result<ExternModule> {
-    use self::std;
     ExternModule::new(
         vm,
         record! {
@@ -532,7 +528,6 @@ pub fn load_int(vm: &Thread) -> Result<ExternModule> {
 
 #[allow(non_camel_case_types)]
 pub fn load_array(vm: &Thread) -> Result<ExternModule> {
-    use self::std;
     ExternModule::new(
         vm,
         record! {
@@ -545,7 +540,6 @@ pub fn load_array(vm: &Thread) -> Result<ExternModule> {
 }
 
 pub fn load_string(vm: &Thread) -> Result<ExternModule> {
-    use self::string;
     ExternModule::new(
         vm,
         record! {
@@ -705,8 +699,6 @@ pub fn load_char(vm: &Thread) -> Result<ExternModule> {
 
 #[allow(non_camel_case_types, deprecated)]
 pub fn load<'vm>(vm: &'vm Thread) -> Result<ExternModule> {
-    use self::std;
-
     vm.define_global(
         "error",
         primitive::<fn(StdString) -> Pushed<A>>("@error", std::prim::error),
diff --git a/vm/src/reference.rs b/vm/src/reference.rs
index 12290ca0..da2b9df4 100644
--- a/vm/src/reference.rs
+++ b/vm/src/reference.rs
@@ -77,8 +77,6 @@ mod std {
 }
 
 pub fn load(vm: &Thread) -> Result<ExternModule> {
-    use self::std;
-
     let _ = vm.register_type::<Reference<A>>("std.reference.Reference", &["a"]);
     ExternModule::new(
         vm,
diff --git a/vm/src/serialization.rs b/vm/src/serialization.rs
index 958c99f2..719f9521 100644
--- a/vm/src/serialization.rs
+++ b/vm/src/serialization.rs
@@ -158,8 +158,6 @@ pub mod gc {
         where
             S: Serializer,
         {
-            use crate::serde::ser::Seeded;
-
             serializer.collect_seq(self.iter().map(|value| Seeded::new(seed, value)))
         }
     }
diff --git a/vm/src/value.rs b/vm/src/value.rs
index dbd3a13f..4a28f05c 100644
--- a/vm/src/value.rs
+++ b/vm/src/value.rs
@@ -1,9 +1,9 @@
-use std::collections::hash_map::Entry;
-use std::fmt;
-use std::iter;
-use std::mem;
-use std::mem::size_of;
-use std::result::Result as StdResult;
+use std::{
+    collections::hash_map::Entry,
+    fmt, iter,
+    mem::{self, size_of},
+    result::Result as StdResult,
+};
 
 use itertools::Itertools;
 
@@ -629,8 +629,6 @@ impl<'a> fmt::Display for ValuePrinter<'a> {
 
 impl<'a, 't> InternalPrinter<'a, 't> {
     fn pretty(&self, value: Variants) -> DocBuilder<'a, Arena<'a>> {
-        use std::iter;
-
         let arena = self.arena;
         match value.0 {
             _ if self.level == 0 => arena.text(".."),
@@ -885,7 +883,6 @@ impl<'b> Traverseable for PartialApplicationDataDef<'b> {
 unsafe impl<'b> DataDef for PartialApplicationDataDef<'b> {
     type Value = PartialApplicationData;
     fn size(&self) -> usize {
-        use std::mem::size_of;
         size_of::<PartialApplicationData>() + size_of::<Value>() * self.1.len()
     }
     fn initialize<'w>(
@@ -1088,7 +1085,6 @@ macro_rules! impl_repr {
         unsafe impl<'a> DataDef for &'a [$id] {
             type Value = ValueArray;
             fn size(&self) -> usize {
-                use std::mem::size_of;
                 size_of::<ValueArray>() + self.len() * size_of::<$id>()
             }
             fn initialize<'w>(self, mut result: WriteOnly<'w, ValueArray>) -> &'w mut ValueArray {
@@ -1113,7 +1109,6 @@ macro_rules! impl_repr {
         )*
         impl Repr {
             fn size_of(self) -> usize {
-                use std::mem::size_of;
                 match self {
                     $(
                         $repr => size_of::<$id>(),
@@ -1356,7 +1351,6 @@ impl<'b> Traverseable for ArrayDef<'b> {
 unsafe impl<'b> DataDef for ArrayDef<'b> {
     type Value = ValueArray;
     fn size(&self) -> usize {
-        use std::mem::size_of;
         let size = match self.0.first() {
             Some(value) => Repr::from_value(value).size_of() * self.0.len(),
             None => 0,


Test patch:
diff --git a/check/tests/metadata.rs b/check/tests/metadata.rs
index 73c841d2..1984ed92 100644
--- a/check/tests/metadata.rs
+++ b/check/tests/metadata.rs
@@ -116,6 +116,31 @@ type Test = Int
     );
 }
 
+#[test]
+fn propagate_metadata_parens() {
+    let _ = env_logger::try_init();
+
+    let text = r#"
+/// The identity function
+let id x = x
+id
+"#;
+    let (mut expr, result) = support::typecheck_expr(text);
+
+    assert!(result.is_ok(), "{}", result.unwrap_err());
+
+    let metadata = metadata(&MockEnv, &mut expr);
+    assert_eq!(
+        metadata,
+        Metadata {
+            definition: Some(intern("id:32")),
+            comment: Some(line_comment("The identity function")),
+            args: vec![Argument::explicit(intern("x:35"))],
+            ..Metadata::default()
+        }
+    );
+}
+
 #[test]
 fn propagate_metadata_record_field_comment() {
     let _ = env_logger::try_init();
diff --git a/tests/pass/lazyt.glu b/tests/pass/lazyt.glu
deleted file mode 100644
index 80a6b1ed..00000000
--- a/tests/pass/lazyt.glu
+++ /dev/null
@@ -1,34 +0,0 @@
-let { (<|) } = import! std.function
-let { Test, run, assert, assert_eq, test, group, ? } = import! std.test
-let { LazyT, force_t, ? } = import! std.lazyt
-let { Functor, map } = import! std.functor
-let { Applicative, wrap, (*>) } = import! std.applicative
-let { Monad, (>>=) } = import! std.monad
-let { Transformer, wrap_monad } = import! std.transformer
-let { Option, unwrap, ? } = import! std.option
-let { (++), ? } = import! std.string
-let list @ { List, ? } = import! std.list
-
-
-let left_identity x f : [Eq a] -> [Show a] -> a -> (a -> LazyT Option a) -> _ = \_ ->
-    let mx : LazyT Option _ = wrap x
-    assert_eq (force_t (mx >>= f)) (force_t (f x))
-
-let right_identity x : [Eq a] -> [Show a] -> a -> _ = \_ ->
-    let mx : LazyT Option _ = wrap x
-    assert_eq (force_t (mx >>= wrap)) (force_t mx)
-
-let associativity mx f g : [Monad m] -> [Show (m a)] -> [Eq (m a)] -> m a -> _ -> _ -> _ = \_ ->
-    let mx : LazyT m _ = wrap_monad mx
-    assert_eq (force_t ((mx >>= f) >>= g)) (force_t (mx >>= (\x -> f x >>= g)))
-
-group "lazyt" [
-    group "LazyT m is monadic" [
-        test "left identity" <| left_identity 324 (\x -> wrap <| x + 89),
-        test "right identity" <| right_identity "hello",
-        test "associativity" <| associativity (Some 5) (\x -> wrap (x+5)) (\x -> wrap (x*2)),
-    ],
-    let x = list.of [8,6,7,5,3,0,9]
-    let f = (*) 42
-    test "LazyT m is lazy" <| \_ -> assert_eq (map f x) (force_t <| map f <| wrap_monad x),
-]
diff --git a/tests/pass/statet.glu b/tests/pass/statet.glu
deleted file mode 100644
index cc59840c..00000000
--- a/tests/pass/statet.glu
+++ /dev/null
@@ -1,45 +0,0 @@
-let { (<|) } = import! std.function
-let { Test, run, assert, assert_eq, test, group, ? } = import! std.test
-let { StateT, put, get, gets, modify, run_state_t, eval_state_t, exec_state_t, ? } = import! std.statet
-let { wrap, (*>) } = import! std.applicative
-let { Monad, (>>=) } = import! std.monad
-let { Option, unwrap, ? } = import! std.option
-let { (++), ? } = import! std.string
-let list @ { List, ? } = import! std.list
-let { Transformer, wrap_monad } = import! std.transformer
-
-#[infix(right,7)]
-let (::) x xs = Cons x xs
-
-let left_identity x f : [Eq a] -> [Show a] -> a -> (a -> StateT _ Option a) -> _ = \_ ->
-    let mx : StateT _ Option _ = wrap x
-    let s = ()
-    assert_eq (eval_state_t (mx >>= f) s) (eval_state_t (f x) s)
-
-let right_identity x : [Eq a] -> [Show a] -> a -> _ = \_ ->
-    let mx : StateT _ Option _ = wrap x
-    let s = ()
-    assert_eq (eval_state_t (mx >>= wrap) s) (eval_state_t mx s)
-
-let associativity ?mo mx f g : [Monad m] -> [Show (m a)] -> [Eq (m a)] -> m a -> _ -> _ -> _ = \_ ->
-    let mx : StateT _ m _ = wrap_monad mx
-    let s = ()
-    assert_eq (eval_state_t ((mx >>= f) >>= g) s) (eval_state_t (mx >>= (\x -> f x >>= g)) s)
-
-group "statet" [
-    // should this be moved to std.monad?
-    group "StateT s m is monadic" [
-        test "left identity" <| left_identity 324 (\x -> wrap <| x + 89),
-        test "right identity" <| right_identity "hello",
-        test "associativity" <| associativity (Some 5) (\x -> wrap (x+5)) (\x -> wrap (x*2)),
-    ],
-    group "StateT s m has state effects" [
-        test "modify exec_state_t" <| \_ -> (assert_eq (exec_state_t (modify (\x -> x + 2) *> modify (\x -> x * 4)) 0) <| Some 8),
-        test "modify eval_state_t" <| \_ -> (assert_eq (eval_state_t (modify (\x -> x + 2) *> get) 0) <| Some 2),
-        test "put get eval_state_t" <| \_ -> (assert_eq (eval_state_t (put "hello" *> get) "") <| Some "hello"),
-        #[derive(Eq, Show)]
-        type StateOut s a = { value : a, state : s }
-        test "put get run_state_t" <| \_ -> (assert_eq (run_state_t (put "hello" *> get) "") <| Some {value = "hello", state = "hello"}),
-        test "gets eval_state_t" <| \_ -> (assert_eq (eval_state_t (gets <| (::) 1) (2 :: 3 :: Nil)) <| Some (1 :: 2 :: 3 :: Nil)),
-    ],
-]