tamer: f::{Functor=>Map}: It's not really a functor
At least not how most people expect functors to be. I'm really just using this as a map with powerful inference properties that make writing code more pleasent. And I need fallible methods now too. DEV-13163main
parent
e14854a555
commit
38c0161257
|
@ -36,7 +36,7 @@ use super::{
|
|||
use crate::{
|
||||
diagnose::Annotate,
|
||||
diagnostic_unreachable,
|
||||
f::Functor,
|
||||
f::Map,
|
||||
parse::{prelude::*, StateStack},
|
||||
span::Span,
|
||||
sym::SymbolId,
|
||||
|
@ -1310,7 +1310,7 @@ impl<T> AsRef<T> for EnvScopeKind<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, U> Functor<T, U> for EnvScopeKind<T> {
|
||||
impl<T, U> Map<T, U> for EnvScopeKind<T> {
|
||||
type Target = EnvScopeKind<U>;
|
||||
|
||||
fn map(self, f: impl FnOnce(T) -> U) -> Self::Target {
|
||||
|
|
|
@ -31,7 +31,7 @@ use super::{
|
|||
};
|
||||
use crate::{
|
||||
asg::{graph::object::ObjectIndexTo, ObjectKind},
|
||||
f::Functor,
|
||||
f::Map,
|
||||
parse::prelude::*,
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ use self::object::{
|
|||
use super::{AsgError, Object, ObjectIndex, ObjectKind};
|
||||
use crate::{
|
||||
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
|
||||
f::Functor,
|
||||
f::Map,
|
||||
global,
|
||||
span::Span,
|
||||
};
|
||||
|
|
|
@ -123,7 +123,7 @@ use super::{Asg, AsgError};
|
|||
use crate::{
|
||||
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
|
||||
diagnostic_panic,
|
||||
f::Functor,
|
||||
f::Map,
|
||||
parse::util::SPair,
|
||||
span::{Span, UNKNOWN_SPAN},
|
||||
};
|
||||
|
@ -924,7 +924,7 @@ impl ObjectIndex<Object> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<O: ObjectKind> Functor<Span> for ObjectIndex<O> {
|
||||
impl<O: ObjectKind> Map<Span> for ObjectIndex<O> {
|
||||
fn map(self, f: impl FnOnce(Span) -> Span) -> Self {
|
||||
match self {
|
||||
Self(index, span, ph) => Self(index, f(span), ph),
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
//! Expressions on the ASG.
|
||||
|
||||
use super::{prelude::*, Doc, Ident, ObjectIndexTo, Tpl};
|
||||
use crate::{f::Functor, num::Dim, span::Span};
|
||||
use crate::{f::Map, num::Dim, span::Span};
|
||||
use std::fmt::Display;
|
||||
|
||||
#[cfg(doc)]
|
||||
|
@ -52,7 +52,7 @@ impl Expr {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<Span> for Expr {
|
||||
impl Map<Span> for Expr {
|
||||
fn map(self, f: impl FnOnce(Span) -> Span) -> Self {
|
||||
match self {
|
||||
Self(op, dim, span) => Self(op, dim, f(span)),
|
||||
|
|
|
@ -23,7 +23,7 @@ use super::{prelude::*, Expr, Meta, Pkg, Tpl};
|
|||
use crate::{
|
||||
diagnose::{panic::DiagnosticPanic, Annotate, Diagnostic},
|
||||
diagnostic_todo,
|
||||
f::Functor,
|
||||
f::Map,
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
num::{Dim, Dtype},
|
||||
parse::{util::SPair, Token},
|
||||
|
|
|
@ -36,7 +36,7 @@ use super::{prelude::*, Doc, Ident};
|
|||
use crate::{
|
||||
diagnose::Annotate,
|
||||
diagnostic_todo,
|
||||
f::Functor,
|
||||
f::Map,
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
parse::{util::SPair, Token},
|
||||
span::Span,
|
||||
|
@ -156,7 +156,7 @@ impl Display for Meta {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<Span> for Meta {
|
||||
impl Map<Span> for Meta {
|
||||
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
||||
match self {
|
||||
Self::Required(span) => Self::Required(f(span)),
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
use super::{prelude::*, Doc, Ident, Tpl};
|
||||
use crate::{
|
||||
f::Functor,
|
||||
f::Map,
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
parse::{util::SPair, Token},
|
||||
span::Span,
|
||||
|
@ -87,7 +87,7 @@ impl Display for Pkg {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<Span> for Pkg {
|
||||
impl Map<Span> for Pkg {
|
||||
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
||||
match self {
|
||||
Self(span, path) => Self(f(span), path),
|
||||
|
|
|
@ -30,7 +30,7 @@ use crate::{
|
|||
graph::{object::Tpl, AsgRelMut},
|
||||
Asg, AsgError,
|
||||
},
|
||||
f::Functor,
|
||||
f::Map,
|
||||
span::Span,
|
||||
};
|
||||
use std::{fmt::Display, marker::PhantomData};
|
||||
|
@ -481,7 +481,7 @@ impl DynObjectRel<ObjectIndex<Object>, ObjectIndex<Object>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S, T, U, V> Functor<(S, T), (U, V)> for DynObjectRel<S, T> {
|
||||
impl<S, T, U, V> Map<(S, T), (U, V)> for DynObjectRel<S, T> {
|
||||
type Target = DynObjectRel<U, V>;
|
||||
|
||||
fn map(self, f: impl FnOnce((S, T)) -> (U, V)) -> Self::Target {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use super::{prelude::*, Doc, Expr, Ident};
|
||||
use crate::{f::Functor, parse::util::SPair, span::Span};
|
||||
use crate::{f::Map, parse::util::SPair, span::Span};
|
||||
|
||||
/// Template with associated name.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -46,7 +46,7 @@ impl Tpl {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<Span> for Tpl {
|
||||
impl Map<Span> for Tpl {
|
||||
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
||||
match self {
|
||||
Self(span, shape) => Self(f(span), shape),
|
||||
|
@ -54,7 +54,7 @@ impl Functor<Span> for Tpl {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<TplShape> for Tpl {
|
||||
impl Map<TplShape> for Tpl {
|
||||
fn map(self, f: impl FnOnce(TplShape) -> TplShape) -> Self::Target {
|
||||
match self {
|
||||
Self(span, shape) => Self(span, f(shape)),
|
||||
|
|
|
@ -24,7 +24,7 @@ use crate::{
|
|||
graph::object::ObjectRelTy,
|
||||
ExprOp,
|
||||
},
|
||||
f::Functor,
|
||||
f::Map,
|
||||
parse::{
|
||||
util::{spair, SPair},
|
||||
ParseState,
|
||||
|
|
|
@ -33,11 +33,12 @@
|
|||
|
||||
/// A type providing a `map` function from inner type `T` to `U`.
|
||||
///
|
||||
/// In an abuse of terminology,
|
||||
/// this functor is polymorphic over the entire trait,
|
||||
/// This used to be called `Functor`,
|
||||
/// but was renamed because it was an abuse of terminology;
|
||||
/// this is polymorphic over the entire trait,
|
||||
/// rather than just the definition of `map`,
|
||||
/// allowing implementations to provide multiple specialized `map`s
|
||||
/// without having to define individual `map_*` methods.
|
||||
/// allowing implementations to provide multiple specialized `map`s
|
||||
/// without having to define individual `map_*` methods.
|
||||
/// Rust will often be able to infer the proper types and invoke the
|
||||
/// intended `map` function within a given context,
|
||||
/// but methods may still be explicitly disambiguated using the
|
||||
|
@ -46,16 +47,13 @@
|
|||
/// if a functor requires a monomorphic function
|
||||
/// (so `T = U`),
|
||||
/// then it's not really a functor.
|
||||
/// We'll refer to these structures informally as monomorphic functors,
|
||||
/// since they provide the same type of API as a functor,
|
||||
/// but cannot change the underlying type.
|
||||
///
|
||||
/// This trait also provides a number of convenience methods that can be
|
||||
/// implemented in terms of [`Functor::map`].
|
||||
/// implemented in terms of [`Map::map`].
|
||||
///
|
||||
/// Why a primitive `map` instead of `fmap`?
|
||||
/// ========================================
|
||||
/// One of the methods of this trait is [`Functor::fmap`],
|
||||
/// One of the methods of this trait is [`Map::fmap`],
|
||||
/// which [is motivated by Haskell][haskell-functor].
|
||||
/// This trait implements methods in terms of [`map`](Self::map) rather than
|
||||
/// [`fmap`](Self::fmap) because `map` is a familiar idiom in Rust and
|
||||
|
@ -66,8 +64,8 @@
|
|||
/// which is additional boilerplate relative to `map`.
|
||||
///
|
||||
/// [haskell-functor]: https://hackage.haskell.org/package/base/docs/Data-Functor.html
|
||||
pub trait Functor<T, U = T>: Sized {
|
||||
/// Type of object resulting from [`Functor::map`] operation.
|
||||
pub trait Map<T, U = T>: Sized {
|
||||
/// Type of object resulting from [`Map::map`] operation.
|
||||
///
|
||||
/// The term "target" originates from category theory,
|
||||
/// representing the codomain of the functor.
|
||||
|
@ -83,7 +81,7 @@ pub trait Functor<T, U = T>: Sized {
|
|||
/// all others are implemented in terms of it.
|
||||
fn map(self, f: impl FnOnce(T) -> U) -> Self::Target;
|
||||
|
||||
/// Curried form of [`Functor::map`],
|
||||
/// Curried form of [`Map::map`],
|
||||
/// with arguments reversed.
|
||||
///
|
||||
/// `fmap` returns a unary closure that accepts an object of type
|
||||
|
@ -106,22 +104,22 @@ pub trait Functor<T, U = T>: Sized {
|
|||
///
|
||||
/// This is intended for cases where there's a single element that will
|
||||
/// be replaced,
|
||||
/// taking advantage of [`Functor`]'s trait-level polymorphism.
|
||||
/// taking advantage of [`Map`]'s trait-level polymorphism.
|
||||
fn overwrite(self, value: U) -> Self::Target {
|
||||
self.map(|_| value)
|
||||
}
|
||||
|
||||
/// Curried form of [`Functor::overwrite`],
|
||||
/// Curried form of [`Map::overwrite`],
|
||||
/// with arguments reversed.
|
||||
fn foverwrite(value: U) -> impl FnOnce(Self) -> Self::Target {
|
||||
move |x| x.overwrite(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Functor<T, U> for Option<T> {
|
||||
impl<T, U> Map<T, U> for Option<T> {
|
||||
type Target = Option<U>;
|
||||
|
||||
fn map(self, f: impl FnOnce(T) -> U) -> <Self as Functor<T, U>>::Target {
|
||||
fn map(self, f: impl FnOnce(T) -> U) -> <Self as Map<T, U>>::Target {
|
||||
Option::map(self, f)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ mod tplshort;
|
|||
|
||||
use crate::{
|
||||
diagnose::{Annotate, Diagnostic},
|
||||
f::Functor,
|
||||
f::Map,
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
parse::{util::SPair, Object, Token},
|
||||
span::Span,
|
||||
|
@ -228,7 +228,7 @@ impl Nir {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<SymbolId> for Nir {
|
||||
impl Map<SymbolId> for Nir {
|
||||
/// Map over a token's [`SymbolId`].
|
||||
///
|
||||
/// This allows modifying a token's [`SymbolId`] while retaining the
|
||||
|
|
|
@ -108,7 +108,7 @@ use memchr::memchr2;
|
|||
use super::{Nir, NirEntity};
|
||||
use crate::{
|
||||
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan, Diagnostic},
|
||||
f::Functor,
|
||||
f::Map,
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
parse::{prelude::*, util::SPair, NoContext},
|
||||
span::Span,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
//! to use outside of the domain of the parsing system itself.
|
||||
|
||||
use super::{prelude::*, state::TransitionData};
|
||||
use crate::{f::Functor, span::Span, sym::SymbolId};
|
||||
use crate::{f::Map, span::Span, sym::SymbolId};
|
||||
use std::fmt::Display;
|
||||
|
||||
/// A [`SymbolId`] with a corresponding [`Span`].
|
||||
|
@ -83,7 +83,7 @@ impl SPair {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<SymbolId> for SPair {
|
||||
impl Map<SymbolId> for SPair {
|
||||
/// Map over the [`SymbolId`] of the pair while retaining the original
|
||||
/// associated [`Span`].
|
||||
///
|
||||
|
@ -98,7 +98,7 @@ impl Functor<SymbolId> for SPair {
|
|||
}
|
||||
}
|
||||
|
||||
impl Functor<Span> for SPair {
|
||||
impl Map<Span> for SPair {
|
||||
/// Map over the [`Span`] of the pair while retaining the associated
|
||||
/// [`SymbolId`].
|
||||
///
|
||||
|
|
|
@ -101,7 +101,7 @@ use super::{
|
|||
CloseSpan, OpenSpan, QName,
|
||||
};
|
||||
use crate::{
|
||||
f::Functor,
|
||||
f::Map,
|
||||
parse::prelude::*,
|
||||
span::{Span, UNKNOWN_SPAN},
|
||||
xir::EleSpan,
|
||||
|
|
|
@ -46,7 +46,7 @@ use super::{
|
|||
CloseSpan, OpenSpan, QName, Token as XirToken, TokenStream,
|
||||
};
|
||||
use crate::{
|
||||
f::Functor,
|
||||
f::Map,
|
||||
parse::prelude::*,
|
||||
span::Span,
|
||||
sym::{st::is_common_whitespace, GlobalSymbolResolve, SymbolId},
|
||||
|
@ -248,7 +248,7 @@ impl<T: TextType> From<Attr> for XirfToken<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: TextType> Functor<Depth> for XirfToken<T> {
|
||||
impl<T: TextType> Map<Depth> for XirfToken<T> {
|
||||
fn map(self, f: impl FnOnce(Depth) -> Depth) -> Self::Target {
|
||||
use XirfToken::*;
|
||||
|
||||
|
|
Loading…
Reference in New Issue