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::{
|
use crate::{
|
||||||
diagnose::Annotate,
|
diagnose::Annotate,
|
||||||
diagnostic_unreachable,
|
diagnostic_unreachable,
|
||||||
f::Functor,
|
f::Map,
|
||||||
parse::{prelude::*, StateStack},
|
parse::{prelude::*, StateStack},
|
||||||
span::Span,
|
span::Span,
|
||||||
sym::SymbolId,
|
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>;
|
type Target = EnvScopeKind<U>;
|
||||||
|
|
||||||
fn map(self, f: impl FnOnce(T) -> U) -> Self::Target {
|
fn map(self, f: impl FnOnce(T) -> U) -> Self::Target {
|
||||||
|
|
|
@ -31,7 +31,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
asg::{graph::object::ObjectIndexTo, ObjectKind},
|
asg::{graph::object::ObjectIndexTo, ObjectKind},
|
||||||
f::Functor,
|
f::Map,
|
||||||
parse::prelude::*,
|
parse::prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ use self::object::{
|
||||||
use super::{AsgError, Object, ObjectIndex, ObjectKind};
|
use super::{AsgError, Object, ObjectIndex, ObjectKind};
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
|
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
|
||||||
f::Functor,
|
f::Map,
|
||||||
global,
|
global,
|
||||||
span::Span,
|
span::Span,
|
||||||
};
|
};
|
||||||
|
|
|
@ -123,7 +123,7 @@ use super::{Asg, AsgError};
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
|
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
|
||||||
diagnostic_panic,
|
diagnostic_panic,
|
||||||
f::Functor,
|
f::Map,
|
||||||
parse::util::SPair,
|
parse::util::SPair,
|
||||||
span::{Span, UNKNOWN_SPAN},
|
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 {
|
fn map(self, f: impl FnOnce(Span) -> Span) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self(index, span, ph) => Self(index, f(span), ph),
|
Self(index, span, ph) => Self(index, f(span), ph),
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
//! Expressions on the ASG.
|
//! Expressions on the ASG.
|
||||||
|
|
||||||
use super::{prelude::*, Doc, Ident, ObjectIndexTo, Tpl};
|
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;
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[cfg(doc)]
|
#[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 {
|
fn map(self, f: impl FnOnce(Span) -> Span) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self(op, dim, span) => Self(op, dim, f(span)),
|
Self(op, dim, span) => Self(op, dim, f(span)),
|
||||||
|
|
|
@ -23,7 +23,7 @@ use super::{prelude::*, Expr, Meta, Pkg, Tpl};
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnose::{panic::DiagnosticPanic, Annotate, Diagnostic},
|
diagnose::{panic::DiagnosticPanic, Annotate, Diagnostic},
|
||||||
diagnostic_todo,
|
diagnostic_todo,
|
||||||
f::Functor,
|
f::Map,
|
||||||
fmt::{DisplayWrapper, TtQuote},
|
fmt::{DisplayWrapper, TtQuote},
|
||||||
num::{Dim, Dtype},
|
num::{Dim, Dtype},
|
||||||
parse::{util::SPair, Token},
|
parse::{util::SPair, Token},
|
||||||
|
|
|
@ -36,7 +36,7 @@ use super::{prelude::*, Doc, Ident};
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnose::Annotate,
|
diagnose::Annotate,
|
||||||
diagnostic_todo,
|
diagnostic_todo,
|
||||||
f::Functor,
|
f::Map,
|
||||||
fmt::{DisplayWrapper, TtQuote},
|
fmt::{DisplayWrapper, TtQuote},
|
||||||
parse::{util::SPair, Token},
|
parse::{util::SPair, Token},
|
||||||
span::Span,
|
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 {
|
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
||||||
match self {
|
match self {
|
||||||
Self::Required(span) => Self::Required(f(span)),
|
Self::Required(span) => Self::Required(f(span)),
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
use super::{prelude::*, Doc, Ident, Tpl};
|
use super::{prelude::*, Doc, Ident, Tpl};
|
||||||
use crate::{
|
use crate::{
|
||||||
f::Functor,
|
f::Map,
|
||||||
fmt::{DisplayWrapper, TtQuote},
|
fmt::{DisplayWrapper, TtQuote},
|
||||||
parse::{util::SPair, Token},
|
parse::{util::SPair, Token},
|
||||||
span::Span,
|
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 {
|
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
||||||
match self {
|
match self {
|
||||||
Self(span, path) => Self(f(span), path),
|
Self(span, path) => Self(f(span), path),
|
||||||
|
|
|
@ -30,7 +30,7 @@ use crate::{
|
||||||
graph::{object::Tpl, AsgRelMut},
|
graph::{object::Tpl, AsgRelMut},
|
||||||
Asg, AsgError,
|
Asg, AsgError,
|
||||||
},
|
},
|
||||||
f::Functor,
|
f::Map,
|
||||||
span::Span,
|
span::Span,
|
||||||
};
|
};
|
||||||
use std::{fmt::Display, marker::PhantomData};
|
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>;
|
type Target = DynObjectRel<U, V>;
|
||||||
|
|
||||||
fn map(self, f: impl FnOnce((S, T)) -> (U, V)) -> Self::Target {
|
fn map(self, f: impl FnOnce((S, T)) -> (U, V)) -> Self::Target {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use super::{prelude::*, Doc, Expr, Ident};
|
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.
|
/// Template with associated name.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[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 {
|
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
||||||
match self {
|
match self {
|
||||||
Self(span, shape) => Self(f(span), shape),
|
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 {
|
fn map(self, f: impl FnOnce(TplShape) -> TplShape) -> Self::Target {
|
||||||
match self {
|
match self {
|
||||||
Self(span, shape) => Self(span, f(shape)),
|
Self(span, shape) => Self(span, f(shape)),
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::{
|
||||||
graph::object::ObjectRelTy,
|
graph::object::ObjectRelTy,
|
||||||
ExprOp,
|
ExprOp,
|
||||||
},
|
},
|
||||||
f::Functor,
|
f::Map,
|
||||||
parse::{
|
parse::{
|
||||||
util::{spair, SPair},
|
util::{spair, SPair},
|
||||||
ParseState,
|
ParseState,
|
||||||
|
|
|
@ -33,8 +33,9 @@
|
||||||
|
|
||||||
/// A type providing a `map` function from inner type `T` to `U`.
|
/// A type providing a `map` function from inner type `T` to `U`.
|
||||||
///
|
///
|
||||||
/// In an abuse of terminology,
|
/// This used to be called `Functor`,
|
||||||
/// this functor is polymorphic over the entire trait,
|
/// but was renamed because it was an abuse of terminology;
|
||||||
|
/// this is polymorphic over the entire trait,
|
||||||
/// rather than just the definition of `map`,
|
/// rather than just the definition of `map`,
|
||||||
/// allowing implementations to provide multiple specialized `map`s
|
/// allowing implementations to provide multiple specialized `map`s
|
||||||
/// without having to define individual `map_*` methods.
|
/// without having to define individual `map_*` methods.
|
||||||
|
@ -46,16 +47,13 @@
|
||||||
/// if a functor requires a monomorphic function
|
/// if a functor requires a monomorphic function
|
||||||
/// (so `T = U`),
|
/// (so `T = U`),
|
||||||
/// then it's not really a functor.
|
/// 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
|
/// 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`?
|
/// 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].
|
/// which [is motivated by Haskell][haskell-functor].
|
||||||
/// This trait implements methods in terms of [`map`](Self::map) rather than
|
/// This trait implements methods in terms of [`map`](Self::map) rather than
|
||||||
/// [`fmap`](Self::fmap) because `map` is a familiar idiom in Rust and
|
/// [`fmap`](Self::fmap) because `map` is a familiar idiom in Rust and
|
||||||
|
@ -66,8 +64,8 @@
|
||||||
/// which is additional boilerplate relative to `map`.
|
/// which is additional boilerplate relative to `map`.
|
||||||
///
|
///
|
||||||
/// [haskell-functor]: https://hackage.haskell.org/package/base/docs/Data-Functor.html
|
/// [haskell-functor]: https://hackage.haskell.org/package/base/docs/Data-Functor.html
|
||||||
pub trait Functor<T, U = T>: Sized {
|
pub trait Map<T, U = T>: Sized {
|
||||||
/// Type of object resulting from [`Functor::map`] operation.
|
/// Type of object resulting from [`Map::map`] operation.
|
||||||
///
|
///
|
||||||
/// The term "target" originates from category theory,
|
/// The term "target" originates from category theory,
|
||||||
/// representing the codomain of the functor.
|
/// 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.
|
/// all others are implemented in terms of it.
|
||||||
fn map(self, f: impl FnOnce(T) -> U) -> Self::Target;
|
fn map(self, f: impl FnOnce(T) -> U) -> Self::Target;
|
||||||
|
|
||||||
/// Curried form of [`Functor::map`],
|
/// Curried form of [`Map::map`],
|
||||||
/// with arguments reversed.
|
/// with arguments reversed.
|
||||||
///
|
///
|
||||||
/// `fmap` returns a unary closure that accepts an object of type
|
/// `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
|
/// This is intended for cases where there's a single element that will
|
||||||
/// be replaced,
|
/// 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 {
|
fn overwrite(self, value: U) -> Self::Target {
|
||||||
self.map(|_| value)
|
self.map(|_| value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Curried form of [`Functor::overwrite`],
|
/// Curried form of [`Map::overwrite`],
|
||||||
/// with arguments reversed.
|
/// with arguments reversed.
|
||||||
fn foverwrite(value: U) -> impl FnOnce(Self) -> Self::Target {
|
fn foverwrite(value: U) -> impl FnOnce(Self) -> Self::Target {
|
||||||
move |x| x.overwrite(value)
|
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>;
|
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)
|
Option::map(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ mod tplshort;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnose::{Annotate, Diagnostic},
|
diagnose::{Annotate, Diagnostic},
|
||||||
f::Functor,
|
f::Map,
|
||||||
fmt::{DisplayWrapper, TtQuote},
|
fmt::{DisplayWrapper, TtQuote},
|
||||||
parse::{util::SPair, Object, Token},
|
parse::{util::SPair, Object, Token},
|
||||||
span::Span,
|
span::Span,
|
||||||
|
@ -228,7 +228,7 @@ impl Nir {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Functor<SymbolId> for Nir {
|
impl Map<SymbolId> for Nir {
|
||||||
/// Map over a token's [`SymbolId`].
|
/// Map over a token's [`SymbolId`].
|
||||||
///
|
///
|
||||||
/// This allows modifying a token's [`SymbolId`] while retaining the
|
/// This allows modifying a token's [`SymbolId`] while retaining the
|
||||||
|
|
|
@ -108,7 +108,7 @@ use memchr::memchr2;
|
||||||
use super::{Nir, NirEntity};
|
use super::{Nir, NirEntity};
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan, Diagnostic},
|
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan, Diagnostic},
|
||||||
f::Functor,
|
f::Map,
|
||||||
fmt::{DisplayWrapper, TtQuote},
|
fmt::{DisplayWrapper, TtQuote},
|
||||||
parse::{prelude::*, util::SPair, NoContext},
|
parse::{prelude::*, util::SPair, NoContext},
|
||||||
span::Span,
|
span::Span,
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
//! to use outside of the domain of the parsing system itself.
|
//! to use outside of the domain of the parsing system itself.
|
||||||
|
|
||||||
use super::{prelude::*, state::TransitionData};
|
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;
|
use std::fmt::Display;
|
||||||
|
|
||||||
/// A [`SymbolId`] with a corresponding [`Span`].
|
/// 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
|
/// Map over the [`SymbolId`] of the pair while retaining the original
|
||||||
/// associated [`Span`].
|
/// 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
|
/// Map over the [`Span`] of the pair while retaining the associated
|
||||||
/// [`SymbolId`].
|
/// [`SymbolId`].
|
||||||
///
|
///
|
||||||
|
|
|
@ -101,7 +101,7 @@ use super::{
|
||||||
CloseSpan, OpenSpan, QName,
|
CloseSpan, OpenSpan, QName,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
f::Functor,
|
f::Map,
|
||||||
parse::prelude::*,
|
parse::prelude::*,
|
||||||
span::{Span, UNKNOWN_SPAN},
|
span::{Span, UNKNOWN_SPAN},
|
||||||
xir::EleSpan,
|
xir::EleSpan,
|
||||||
|
|
|
@ -46,7 +46,7 @@ use super::{
|
||||||
CloseSpan, OpenSpan, QName, Token as XirToken, TokenStream,
|
CloseSpan, OpenSpan, QName, Token as XirToken, TokenStream,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
f::Functor,
|
f::Map,
|
||||||
parse::prelude::*,
|
parse::prelude::*,
|
||||||
span::Span,
|
span::Span,
|
||||||
sym::{st::is_common_whitespace, GlobalSymbolResolve, SymbolId},
|
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 {
|
fn map(self, f: impl FnOnce(Depth) -> Depth) -> Self::Target {
|
||||||
use XirfToken::*;
|
use XirfToken::*;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue