pub struct Tensor { /* private fields */ }Expand description
A symbolic tensor in a traced graph.
Lazy by construction. Despite the eager-looking operator syntax, a
Tensor is a deferred handle: &a + &b, .relu(), .matmul(..) etc.
only append IR nodes — no host or device buffers are allocated and nothing
executes. The graph is compiled (fused + memory-planned) and run only
when you force it with to_vec / realize
(both require the eval feature). This is what lets the whole expression
fuse instead of materializing every intermediate.
Zero-copy clone & slice. clone() just bumps a refcount on the shared
graph handle — no data is duplicated. slice/narrow/reshape/select
add a view node into the same graph (referencing the parent by id), so
they move zero payload bytes either. Use shares_graph
to observe storage sharing and storage_bytes to
confirm no data was copied. (Combining two independently-constructed
tensors is the one case that copies — the right operand’s nodes are merged
in once; see the handle module.)
Implementations§
Source§impl Tensor
impl Tensor
Sourcepub fn from_vec(data: impl Into<Vec<f32>>, shape: impl AsRef<[usize]>) -> Self
pub fn from_vec(data: impl Into<Vec<f32>>, shape: impl AsRef<[usize]>) -> Self
Constant tensor from row-major host data (F32). The product of shape
must equal data.len().
Sourcepub fn full(shape: impl AsRef<[usize]>, value: f32) -> Self
pub fn full(shape: impl AsRef<[usize]>, value: f32) -> Self
Constant of the given shape filled with value (F32).
Sourcepub fn arange_step(start: i64, end: i64, step: i64) -> Self
pub fn arange_step(start: i64, end: i64, step: i64) -> Self
1-D constant [start, start+step, …) up to (excluding) end (F32).
Sourcepub fn from_f64(data: impl AsRef<[f64]>, shape: impl AsRef<[usize]>) -> Self
pub fn from_f64(data: impl AsRef<[f64]>, shape: impl AsRef<[usize]>) -> Self
F64 (double-precision) constant from host data.
Sourcepub fn from_i64(data: impl AsRef<[i64]>, shape: impl AsRef<[usize]>) -> Self
pub fn from_i64(data: impl AsRef<[i64]>, shape: impl AsRef<[usize]>) -> Self
I64 constant from host data (general N-D).
Sourcepub fn index_vec(data: impl AsRef<[i64]>) -> Self
pub fn index_vec(data: impl AsRef<[i64]>) -> Self
1-D I64 index vector for gather /
index_select.
Sourcepub fn rand(shape: impl AsRef<[usize]>, seed: u64) -> Self
pub fn rand(shape: impl AsRef<[usize]>, seed: u64) -> Self
Uniform random in [0, 1) (F32), reproducible from seed.
Sourcepub fn rand_range(
shape: impl AsRef<[usize]>,
seed: u64,
lo: f32,
hi: f32,
) -> Self
pub fn rand_range( shape: impl AsRef<[usize]>, seed: u64, lo: f32, hi: f32, ) -> Self
Uniform random in [lo, hi) (F32), reproducible from seed.
Source§impl Tensor
impl Tensor
Sourcepub fn to_ndarray(&self) -> ArrayD<f32>
pub fn to_ndarray(&self) -> ArrayD<f32>
Realize (compile + run) and return an owned ndarray::ArrayD<f32>.
Source§impl Tensor
impl Tensor
Sourcepub fn id(&self) -> NodeId
pub fn id(&self) -> NodeId
IR node id (mix with raw rlx_ir::Graph builders via NodeId).
pub fn shape(&self) -> Shape
pub fn dtype(&self) -> DType
pub fn rank(&self) -> usize
Sourcepub fn is_static_shape(&self) -> bool
pub fn is_static_shape(&self) -> bool
True when every dimension is statically known.
True if self and other are backed by the same graph — i.e. one
is a clone or a view (slice/reshape/narrow/…) of the
other, sharing storage with zero copy. Tensors from independent
constructors return false until they’re combined in an op.
Sourcepub fn storage_bytes(&self) -> usize
pub fn storage_bytes(&self) -> usize
Total bytes of constant (payload) data physically held in the backing graph. Cloning and slicing do not increase this — they share storage and only add zero-payload view nodes. Combining tensors from different graphs copies the right-hand operand’s data in (once).
Sourcepub fn slice(&self, spec: SliceSpec) -> Self
pub fn slice(&self, spec: SliceSpec) -> Self
View slice — lowers to narrow (no copy at IR level).
pub fn matmul(&self, rhs: &Tensor) -> Self
Sourcepub fn scaled_matmul(
&self,
rhs: &Tensor,
fmt: ScaledFormat,
layout: ScaleLayout,
) -> Self
pub fn scaled_matmul( &self, rhs: &Tensor, fmt: ScaledFormat, layout: ScaleLayout, ) -> Self
Native low-precision GEMM (TN: self [m,k] · rhs [n,k]ᵀ → [m,n]).
Both operands are dynamically quantized to the minifloat fmt +
layout; rhs must be K-last ([n, k]). fmt may be any
ScaledFormat, including a parameterized Custom — e.g.
t.scaled_matmul(&w, ScaledFormat::custom(3, 0), ScaleLayout::mx()) runs
the matmul in f4e3m0.
pub fn softmax(&self, axis: i32) -> Self
pub fn reshape(&self, new_shape: impl Into<Vec<i64>>) -> Self
pub fn transpose(&self, perm: impl Into<Vec<usize>>) -> Self
pub fn t(&self) -> Self
pub fn cast(&self, to: DType) -> Self
pub fn narrow(&self, axis: usize, start: usize, len: usize) -> Self
Sourcepub fn broadcast_to(&self, shape: impl Into<Vec<i64>>) -> Self
pub fn broadcast_to(&self, shape: impl Into<Vec<i64>>) -> Self
Broadcast (expand) to an explicit target shape — NumPy broadcast_to.
A 1 axis stretches; sizes must otherwise match. Use -1-free static
targets.
Sourcepub fn unsqueeze(&self, axis: usize) -> Self
pub fn unsqueeze(&self, axis: usize) -> Self
Insert a size-1 axis at axis (NumPy expand_dims / PyTorch
unsqueeze).
Sourcepub fn squeeze(&self, axis: usize) -> Self
pub fn squeeze(&self, axis: usize) -> Self
Remove the size-1 axis at axis (panics if it is not size 1).
Sourcepub fn squeeze_all(&self) -> Self
pub fn squeeze_all(&self) -> Self
Remove every size-1 axis.
Sourcepub fn split(&self, axis: usize, sizes: &[usize]) -> Vec<Tensor>
pub fn split(&self, axis: usize, sizes: &[usize]) -> Vec<Tensor>
Split axis into contiguous pieces of the given sizes (must sum to
the axis length). NumPy split / PyTorch split_with_sizes.
Sourcepub fn chunk(&self, axis: usize, n: usize) -> Vec<Tensor>
pub fn chunk(&self, axis: usize, n: usize) -> Vec<Tensor>
Split axis into n near-equal chunks (first len % n get one extra).
Sourcepub fn tile(&self, axis: usize, reps: usize) -> Tensor
pub fn tile(&self, axis: usize, reps: usize) -> Tensor
Repeat the whole tensor reps times along axis (NumPy tile on one
axis): output axis length becomes len * reps.
Sourcepub fn flip(&self, axis: usize) -> Tensor
pub fn flip(&self, axis: usize) -> Tensor
Reverse the order of elements along axis (NumPy flip).
Sourcepub fn roll(&self, axis: usize, shift: usize) -> Tensor
pub fn roll(&self, axis: usize, shift: usize) -> Tensor
Cyclically shift elements along axis by shift (NumPy roll).
Sourcepub fn pad(
&self,
axis: usize,
before: usize,
after: usize,
value: f32,
) -> Tensor
pub fn pad( &self, axis: usize, before: usize, after: usize, value: f32, ) -> Tensor
Pad axis with before/after entries of value (constant pad).
pub fn gather(&self, indices: &Tensor, axis: usize) -> Self
Sourcepub fn index_select(&self, axis: usize, indices: &Tensor) -> Self
pub fn index_select(&self, axis: usize, indices: &Tensor) -> Self
Gather along axis by an index tensor — NumPy take / PyTorch
index_select. Alias for gather.
Sourcepub fn select(&self, axis: usize, index: i64) -> Self
pub fn select(&self, axis: usize, index: i64) -> Self
Pick a single position along axis, dropping that axis (NumPy
a[…, i, …]). Negative index counts from the end.
pub fn stop_gradient(&self) -> Self
Sourcepub fn argmax(&self, axis: usize, keep_dim: bool) -> Self
pub fn argmax(&self, axis: usize, keep_dim: bool) -> Self
Index of the maximum along axis (f32-encoded indices). Drops the axis
unless keep_dim.
Sourcepub fn argmin(&self, axis: usize, keep_dim: bool) -> Self
pub fn argmin(&self, axis: usize, keep_dim: bool) -> Self
Index of the minimum along axis (f32-encoded indices).
Sourcepub fn inv(&self) -> Self
pub fn inv(&self) -> Self
Matrix inverse of a square 2-D tensor. Composite over DenseSolve
(inv(A) = solve(A, I)), so it needs a BLAS-backed eval build (LAPACK)
to run, not the default splat backend.
Sourcepub fn solve(&self, b: &Tensor) -> Self
pub fn solve(&self, b: &Tensor) -> Self
Solve the linear system self @ x = b for x (LAPACK via DenseSolve;
needs a BLAS eval build). x takes b’s shape.
Sourcepub fn cumsum(&self, axis: i32, exclusive: bool) -> Self
pub fn cumsum(&self, axis: i32, exclusive: bool) -> Self
Cumulative sum along axis. exclusive shifts so output[0] = 0.
Sourcepub fn var(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
pub fn var(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
Population variance over axes: mean((x - mean(x))²).
Sourcepub fn std(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
pub fn std(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
Population standard deviation over axes.
Sourcepub fn norm(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
pub fn norm(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
L2 (Frobenius) norm over axes: sqrt(sum(x²)).
Sourcepub fn logsumexp(&self, axis: usize, keep_dim: bool) -> Self
pub fn logsumexp(&self, axis: usize, keep_dim: bool) -> Self
Numerically-stable log(sum(exp(x))) along axis
(max + log(sum(exp(x - max)))).
Sourcepub fn fft(&self) -> Self
pub fn fft(&self) -> Self
1-D FFT along the last axis (unnormalized; ifft(fft(x)) = N·x).
Complex data uses the [..., 2N] block layout (real plane then imag
plane) for F32/F64, or a C64 last axis. Output matches input shape.
Sourcepub fn ifft(&self) -> Self
pub fn ifft(&self) -> Self
Inverse 1-D FFT along the last axis (unnormalized — pairs with Self::fft
up to the N factor).
Sourcepub fn fft_axis(&self, axis: usize, inverse: bool) -> Self
pub fn fft_axis(&self, axis: usize, inverse: bool) -> Self
1-D FFT along an arbitrary axis (transpose → fft → transpose).
pub fn layer_norm(&self, gamma: &Tensor, beta: &Tensor, eps: f32) -> Self
pub fn rms_norm(&self, gamma: &Tensor, beta: &Tensor, eps: f32) -> Self
Sourcepub fn cross_entropy(&self, targets: &Tensor) -> Self
pub fn cross_entropy(&self, targets: &Tensor) -> Self
Fused softmax + cross-entropy against a dense (soft / one-hot) target
distribution — the standard classifier / language-model loss, in one
differentiable op (native CPU & Metal kernels; lowered to primitives on
other backends). self are logits [N, C], targets a probability
distribution [N, C] (one-hot, or label-smoothed). Returns the per-row
loss [N]: loss[n] = logsumexp(logits[n]) − Σ_c targets[n,c]·logits[n,c].
Reduce it to a scalar training loss with mean_all —
mean(cross_entropy(logits, targets)) in the rlx! DSL. Gradients flow
to both self and targets.
Sourcepub fn softmax_cross_entropy_with_logits(&self, labels: &Tensor) -> Self
pub fn softmax_cross_entropy_with_logits(&self, labels: &Tensor) -> Self
Fused softmax + cross-entropy with integer class labels — PyTorch
cross_entropy(logits, labels, reduction="none"). self are logits
[N, C], labels the f32-encoded class ids [N]. Returns the per-row
loss [N]; reduce with mean_all for a scalar loss.
Sourcepub fn mean_all(&self) -> Self
pub fn mean_all(&self) -> Self
Mean over every axis → a scalar (rank-0). The idiomatic loss reduction
— mean(cross_entropy(logits, targets)) in the rlx! DSL, or
loss.mean_all() in Rust. A rank-0 input is returned unchanged.
Sourcepub fn sum_all(&self) -> Self
pub fn sum_all(&self) -> Self
Sum over every axis → a scalar (rank-0). A rank-0 input is returned unchanged.
pub fn conv2d( &self, weight: &Tensor, kernel_size: [usize; 2], stride: [usize; 2], padding: [usize; 2], dilation: [usize; 2], groups: usize, ) -> Self
pub fn attention( &self, k: &Tensor, v: &Tensor, num_heads: usize, head_dim: usize, mask_kind: MaskKind, ) -> Self
Sourcepub fn synth_matmul(
&self,
indices: &Tensor,
codebook: &Tensor,
entry_dim: u32,
num_entries: u32,
) -> Self
pub fn synth_matmul( &self, indices: &Tensor, codebook: &Tensor, entry_dim: u32, num_entries: u32, ) -> Self
On-chip codebook weight-synthesis matmul (Op::SynthMatMul): y = x·Wᵀ
where the weight [n, k] is reconstructed inside the matmul from indices
[n, k/entry_dim] (u8, fixed quantization structure) + codebook
[num_entries, entry_dim] (f32, trained). x is [m, k], output [m, n].
The codebook is a tiny trainable param; the full weight is never stored —
“functions not data”. Backs rlx-tiny.
Sourcepub fn synth_reconstruct(&self, codebook: &Tensor, entry_dim: u32) -> Self
pub fn synth_reconstruct(&self, codebook: &Tensor, entry_dim: u32) -> Self
Reconstruct the dense weight W [k,n] from self = indices [n, k/entry_dim]
codebook [num_entries, entry_dim](the same gather the SynthMatMul decompose uses, WITHOUT the matmul). Lets a model fold multi-stage VQ + LoRA into ONE effective weight (W_eff = Σ reconstruct + A·Bᵀ) sox·W_effis a single GEMM — dense-speed forward AND a 2-GEMM backward (the multi-stage / LoRA gradients collapse to codebook scatters + rank-r products with no batch dim). For training/prefill (large m); decode keepssynth_matmulin-kernel.
Sourcepub fn spline_activation(
&self,
coeff: &Tensor,
num_basis: u32,
grid_min: f32,
grid_max: f32,
) -> Self
pub fn spline_activation( &self, coeff: &Tensor, num_basis: u32, grid_min: f32, grid_max: f32, ) -> Self
KAN learnable per-channel spline activation (Op::SplineActivation): each
channel c of the last axis gets its own univariate function, a Gaussian-RBF
expansion Σ_g coeff[c,g]·exp(-((x−center_g)·inv_h)²). coeff is
[C, num_basis] (trained); output matches self. A learnable activation
replacing a fixed GELU/ReLU. Backs rlx-tiny.
Sourcepub fn linear(&self, w: &Tensor, b: &Tensor) -> Self
pub fn linear(&self, w: &Tensor, b: &Tensor) -> Self
HuggingFace-style linear x · Wᵀ + b where w is stored [out, in],
as a single fused matmul+bias node (Op::FusedMatMulBiasAct). The
weight transpose is emitted in-graph so callers bind the raw [out, in]
checkpoint tensor directly (no host pre-transpose). Backs the rlx!
linear(x, w, b) / x @t w sugar.
Sourcepub fn linear_act(
&self,
w: &Tensor,
b: &Tensor,
act: Option<Activation>,
) -> Self
pub fn linear_act( &self, w: &Tensor, b: &Tensor, act: Option<Activation>, ) -> Self
linear with a fused elementwise activation applied to
the result — act(x · Wᵀ + b) in one op. Backs gelu(linear(..)) etc.
Sourcepub fn matmul_t(&self, rhs: &Tensor) -> Self
pub fn matmul_t(&self, rhs: &Tensor) -> Self
Matrix multiply against a transposed right operand: self · rhsᵀ
(x @t w in the DSL). Avoids a separate .t() at call sites; the
transpose is emitted in-graph.
Sourcepub fn attention_masked(
&self,
k: &Tensor,
v: &Tensor,
mask: &Tensor,
num_heads: usize,
head_dim: usize,
) -> Self
pub fn attention_masked( &self, k: &Tensor, v: &Tensor, mask: &Tensor, num_heads: usize, head_dim: usize, ) -> Self
Scaled dot-product attention with an explicit [batch, key_len] padding
mask (1.0 = valid, <0.5 = ignored) — the 4-input MaskKind::Custom
form that attention (kernel-synthesized masks) can’t
express. Backs the rlx! attention(q, k, v, mask, heads, head_dim)
sugar.
pub fn rope(&self, cos: &Tensor, sin: &Tensor, head_dim: usize) -> Self
Sourcepub fn where_<'t, 'f>(
&self,
on_true: impl Into<BinaryRhs<'t>>,
on_false: impl Into<BinaryRhs<'f>>,
) -> Self
pub fn where_<'t, 'f>( &self, on_true: impl Into<BinaryRhs<'t>>, on_false: impl Into<BinaryRhs<'f>>, ) -> Self
Select on_true where self (a mask) is true, else on_false. Each
branch is a &Tensor or a scalar (mask.where_(&x, 0.0)), so the
rlx! DSL’s select(mask, x, 0.0) lowers here directly. A scalar
branch is promoted to the other branch’s dtype (else F32).
Sourcepub fn masked_fill(&self, mask: &Tensor, value: f64) -> Self
pub fn masked_fill(&self, mask: &Tensor, value: f64) -> Self
Replace entries of self where mask is true with value (NumPy
masked_fill / the attention-mask primitive: scores.masked_fill(causal, f32::NEG_INFINITY) then softmax). Requires a static shape.
Sourcepub fn maximum<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
pub fn maximum<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
Elementwise maximum (accepts a &Tensor or a scalar).
Sourcepub fn minimum<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
pub fn minimum<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
Elementwise minimum (accepts a &Tensor or a scalar).
Sourcepub fn atan2<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
pub fn atan2<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
Elementwise atan2(self, rhs) — quadrant-aware arctangent.
Sourcepub fn rem<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
pub fn rem<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
Elementwise self % rhs (C fmod; accepts a &Tensor or a scalar).
Sourcepub fn pow<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
pub fn pow<'r>(&self, rhs: impl Into<BinaryRhs<'r>>) -> Self
Elementwise power self ^ rhs (accepts a &Tensor or a scalar).
pub fn pow_scalar(&self, exp: f64) -> Self
Source§impl Tensor
impl Tensor
Sourcepub fn gelu_approx(&self) -> Self
pub fn gelu_approx(&self) -> Self
GELU, tanh approximation.
Sourcepub fn hard_swish(&self) -> Self
pub fn hard_swish(&self) -> Self
HardSwish x·clamp(x+3,0,6)/6.
Sourcepub fn hard_sigmoid(&self) -> Self
pub fn hard_sigmoid(&self) -> Self
HardSigmoid clamp(x/6+0.5,0,1).
Sourcepub fn log_sigmoid(&self) -> Self
pub fn log_sigmoid(&self) -> Self
LogSigmoid log(σ(x)).
Source§impl Tensor
Materialization — compile this tensor’s graph through rlx_runtime and
read the result back to host memory. The graph stays lazy until one of
these is called, so the compiler fuses and memory-plans the whole
expression first. Available with the eval feature.
impl Tensor
Materialization — compile this tensor’s graph through rlx_runtime and
read the result back to host memory. The graph stays lazy until one of
these is called, so the compiler fuses and memory-plans the whole
expression first. Available with the eval feature.
Sourcepub fn to_vec(&self) -> Vec<f32>
pub fn to_vec(&self) -> Vec<f32>
Compile + run and copy the output to a Vec<f32>. The device is chosen
automatically — the fastest backend compiled into this build that can
run the graph (CPU when nothing faster is available).
Sourcepub fn realize(&self) -> Vec<f32>
pub fn realize(&self) -> Vec<f32>
Force evaluation — alias for to_vec. Building a
Tensor allocates nothing and runs nothing; it only records IR.
realize is the single point where the accumulated graph is compiled
(fused + memory-planned) and executed. Use it to make the lazy model
explicit at call sites.
Sourcepub fn to_vec_f64(&self) -> Vec<f64>
pub fn to_vec_f64(&self) -> Vec<f64>
Realize and read back as f64 (tensor dtype must be F64).
Sourcepub fn to_vec_i64(&self) -> Vec<i64>
pub fn to_vec_i64(&self) -> Vec<i64>
Realize and read back as i64 (tensor dtype must be I64).
Sourcepub fn to_vec_i32(&self) -> Vec<i32>
pub fn to_vec_i32(&self) -> Vec<i32>
Realize and read back as i32 (tensor dtype must be I32).
Sourcepub fn to_vec_bool(&self) -> Vec<bool>
pub fn to_vec_bool(&self) -> Vec<bool>
Realize and read back a Bool tensor. Robust to the backend storing
bools 1-byte or f32-encoded (an element is true iff any of its bytes
is non-zero).
Sourcepub fn show(&self) -> String
pub fn show(&self) -> String
Realize and pretty-print with shape + dtype, NumPy/ndarray-style nesting.
println!("{}", t) does the same (with the eval feature).
Sourcepub fn on(&self, device: Device) -> Materialize<'_>
pub fn on(&self, device: Device) -> Materialize<'_>
Select a device fluently: t.on(Device::Metal).to_vec().
Source§impl Tensor
Reverse-mode autodiff. Available with the grad feature; pair with eval
to read the resulting gradient values.
impl Tensor
Reverse-mode autodiff. Available with the grad feature; pair with eval
to read the resulting gradient values.
Sourcepub fn grad(&self, wrt: &[&Tensor]) -> Vec<Tensor>
pub fn grad(&self, wrt: &[&Tensor]) -> Vec<Tensor>
Gradients of this tensor (treated as the loss) w.r.t. each wrt,
returned as symbolic Tensors in the same order as wrt.
The seed ∂self/∂self = 1 is baked in as a constant (ones, matching
self’s shape — so a non-scalar self differentiates sum(self)),
making each returned gradient a self-contained graph you can
to_vec() or compose further.
let loss = (&a * &b).sum([0], false);
let g = loss.grad(&[&a, &b]); // [∂/∂a, ∂/∂b]
assert_eq!(g[0].to_vec(), b.to_vec());Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Tensor
impl !Send for Tensor
impl !Sync for Tensor
impl !UnwindSafe for Tensor
impl Freeze for Tensor
impl Unpin for Tensor
impl UnsafeUnpin for Tensor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more