Conversation
| -- | This tags types (and type constructors) with whether or not they are | ||
| -- strict. | ||
| -- | ||
| -- A type is only strict when all the following conditions hold: | ||
| -- - no referenced type is non-strict | ||
| -- - no non-phantom type parameter is applied to a non-strict type | ||
| -- - all unapplied type parameters are strict (or phantom) | ||
| -- | ||
| -- __FIXME__: This needs a third case (so, @`Maybe` `Bool`@) to distinguish | ||
| -- “simple” types that can be used birecursively, because they have | ||
| -- no recursive structure. | ||
| type family Strict (t :: k) :: Bool |
There was a problem hiding this comment.
This is the main new thing added, and this needs instances for many cases.
On the plus side, if an instance is missing, the type that’s missing an instance won’t work with anything, so they can be added as needed.
| class (IsStrict t, IsStrict f) => Recursive c t f | t -> f where | ||
| cata :: Algebra c f a -> t `c` a |
There was a problem hiding this comment.
Strict goes through a few layers, and is used here (and in Corecursive) to ensure the involved types have the required strictness.
| -- | When the pattern functor is not `Strict`, `Fix` may be used corecursively. | ||
| instance (IsNotStrict (Fix f), Functor f) => Corecursive (->) (Fix f) f where | ||
| ana ψ = embed . fmap (ana ψ) . ψ |
There was a problem hiding this comment.
This is an interesting consequence – when the functor is non-strict, Fix can be used corecursively. However, the same can’t be done with Mu, because embed (and project) on Mu requires cata, which has the IsStrict (Mu f) constraint, which would conflict with the IsNotStrict (Mu f) constraint required by ana.
8831a2b to
4795b96
Compare
0c23eef to
cbb975c
Compare
e770b73 to
6025a49
Compare
This uses a `Strict` type family to tag types and type constructors with their strictness, allowing instances to be constrained more precisely. This mitigates the issue that using a non-strict functor with, say, `Mu` will result in potentially infinite structures, since any functor used with `Mu` must be `Strict` in order to be folded.
6025a49 to
ef98f43
Compare
This uses a
Stricttype family to tag types and type constructors with their strictness, allowing instances to be constrained more precisely.This mitigates the issue that using a non-strict functor with, say,
Muwill result in potentially infinite structures, since any functor used withMumust beStrictin order to be folded.loose ends
Before this PR is complete, the yaya-unsafe:Yaya.Unsafe.Fold.Instances module will go away in favor of instances defined over a
newtype Unsafe tthat will live directly in yaya-unsafe:Yaya.Unsafe.Fold. E.g.,