summaryrefslogtreecommitdiff
path: root/receme/src/hylo.rs
blob: 8d26c1953404b198a5065b77ffd44451d6af74d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//! This file defines the behaviour of hylomorphisms.
//!
//! A hylomorphism is a composition of an anamorphism with a
//! catamorphism.  But it is separated into a distinct trait as we can
//! implement hylomorphisms more efficiently by short-circuiting
//! during the expansion by the anamorphism.

use crate::{
    algebra::Algebra,
    catana::{Ana, Cata},
    coalgebra::Coalgebra,
    functor::Functor,
};

/// A type implementing Hylo is able to expand from a value of type
/// `U` into a recursive structure holding values of type `G`, and
/// also to collapse from that recursive structure to a value of type
/// `T`.
///
/// Types which implement [`Cata`] and [`Ana`] compatibly can
/// automatically implement [`Hylo`] as follows.
///
/// But of course this is not efficient, and types should implement in
/// a more efficient manner, if available.
///
/// ```ignore
/// Inter::ana(value, coalg).cata(alg)
/// ```
pub trait Hylo<T, S, U, F, G, H, A, C>: Cata<T, F, A> + Ana<U, H, C>
where
    F: Functor<T>,
    G: Functor<S, Target<T> = F>,
    H: Functor<U, Target<S> = G>,
    A: Algebra<T, F>,
    C: Coalgebra<U, H>,
{
    /// Expand from `value` to an intermediate recursive structure, by
    /// means of a coalgebra, and then collapse into the result value,
    /// by means of an algebra.
    fn hylo(value: U, alg: A, coalg: C) -> T;
}