diff options
author | Nadrieril | 2019-04-14 19:16:26 +0200 |
---|---|---|
committer | Nadrieril | 2019-04-14 19:16:26 +0200 |
commit | 2223c8ff253fe59fcf365c15221f77b1fc86bd3b (patch) | |
tree | ff702ab9be56c4ff24160ff7deabb754b6f38c27 | |
parent | 7aaa3f1747e6012e51e67edb268414e2c2fb51cd (diff) |
Document why Visitor is needed
Diffstat (limited to '')
-rw-r--r-- | dhall_core/src/visitor.rs | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/dhall_core/src/visitor.rs b/dhall_core/src/visitor.rs index 5eb17f6..3efd920 100644 --- a/dhall_core/src/visitor.rs +++ b/dhall_core/src/visitor.rs @@ -2,10 +2,21 @@ use std::collections::BTreeMap; use crate::*; +/// A way too generic Visitor trait. pub trait GenericVisitor<Input, Return>: Sized { fn visit(self, input: Input) -> Return; } +/// A visitor trait that can be used to traverse `ExprF`s. We need this pattern +/// so that Rust lets us have as much mutability as we can. +/// For example, `traverse_embed` cannot be made using only `traverse_ref`, because +/// `traverse_ref` takes a `FnMut` so we would need to pass multiple mutable +/// reverences to this argument to `traverse_ref`. But Rust's ownership system +/// is all about preventing exactly this ! So we have to be more clever. +/// The visitor pattern allows us to have only one mutable thing the whole +/// time: the visitor itself. The visitor can then carry around multiple closures +/// or just one, and Rust is ok with either. See for example TraverseRefVisitor +/// and TraverseEmbedVisitor. pub trait ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>: Sized { @@ -160,6 +171,7 @@ where } } +/// Like ExprFFallibleVisitor, but without the error handling. pub trait ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>: Sized { |