module Fold.ShortcutNonempty.Conversion where

import Fold.ShortcutNonempty.Type

import Data.Functor.Identity (Identity)
import Fold.Effectful.Type (EffectfulFold)
import Fold.Nonempty.Type (NonemptyFold)
import Fold.Pure.Type (Fold (Fold))
import Fold.Shortcut.Type (ShortcutFold (ShortcutFold))
import Fold.Nonempty.Type (NonemptyFold (NonemptyFold))
import Data.Void (absurd)

import qualified Fold.Pure.Conversion as Fold
import qualified Fold.Pure.Type as Fold
import qualified Fold.Shortcut.Type as Shortcut
import qualified Fold.Nonempty.Type as Nonempty

fold :: Fold a b -> ShortcutNonemptyFold a b
fold :: forall a b. Fold a b -> ShortcutNonemptyFold a b
fold
  Fold{ x
initial :: ()
initial :: x
Fold.initial, x -> a -> x
step :: ()
step :: x -> a -> x
Fold.step, x -> b
extract :: ()
extract :: x -> b
Fold.extract } =
    ShortcutNonemptyFold
      { initial :: a -> Vitality Void x
initial = \a
a -> forall a b. Will -> b -> Vitality a b
Alive Will
Ambivalent (x -> a -> x
step x
initial a
a)
      , step :: x -> a -> Vitality Void x
step = \x
x a
a -> forall a b. Will -> b -> Vitality a b
Alive Will
Ambivalent (x -> a -> x
step x
x a
a)
      , extractDead :: Void -> b
extractDead = forall a. Void -> a
absurd
      , extractLive :: x -> b
extractLive = x -> b
extract
      }

effectfulFold :: EffectfulFold Identity a b -> ShortcutNonemptyFold a b
effectfulFold :: forall a b. EffectfulFold Identity a b -> ShortcutNonemptyFold a b
effectfulFold EffectfulFold Identity a b
x = forall a b. Fold a b -> ShortcutNonemptyFold a b
fold (forall a b. EffectfulFold Identity a b -> Fold a b
Fold.effectfulFold EffectfulFold Identity a b
x)

nonemptyFold :: NonemptyFold a b -> ShortcutNonemptyFold a b
nonemptyFold :: forall a b. NonemptyFold a b -> ShortcutNonemptyFold a b
nonemptyFold
  NonemptyFold{ a -> x
initial :: ()
initial :: a -> x
Nonempty.initial, x -> a -> x
step :: ()
step :: x -> a -> x
Nonempty.step, x -> b
extract :: ()
extract :: x -> b
Nonempty.extract } =
    ShortcutNonemptyFold
      { initial :: a -> Vitality Void x
initial = \a
a -> forall a b. Will -> b -> Vitality a b
Alive Will
Ambivalent (a -> x
initial a
a)
      , step :: x -> a -> Vitality Void x
step = \x
x a
a -> forall a b. Will -> b -> Vitality a b
Alive Will
Ambivalent (x -> a -> x
step x
x a
a)
      , extractDead :: Void -> b
extractDead = forall a. Void -> a
absurd
      , extractLive :: x -> b
extractLive = x -> b
extract
      }

shortcutFold :: ShortcutFold a b -> ShortcutNonemptyFold a b
shortcutFold :: forall a b. ShortcutFold a b -> ShortcutNonemptyFold a b
shortcutFold ShortcutFold{ Vitality x y
initial :: ()
initial :: Vitality x y
Shortcut.initial, y -> a -> Vitality x y
step :: ()
step :: y -> a -> Vitality x y
Shortcut.step,
        x -> b
extractDead :: ()
extractDead :: x -> b
Shortcut.extractDead, y -> b
extractLive :: ()
extractLive :: y -> b
Shortcut.extractLive } =
    ShortcutNonemptyFold
      { initial :: a -> Vitality x y
initial = case Vitality x y
initial of
            Dead    x
x -> \a
_ -> forall a b. a -> Vitality a b
Dead x
x
            Alive Will
_ y
x -> y -> a -> Vitality x y
step y
x
      , step :: y -> a -> Vitality x y
step = y -> a -> Vitality x y
step
      , extractDead :: x -> b
extractDead = x -> b
extractDead
      , extractLive :: y -> b
extractLive = y -> b
extractLive
      }