agda2hs-1.3: lib/Haskell/Extra/Loop.agda
open import Haskell.Prelude
module Haskell.Extra.Loop where
data Fuel (f : a → Either a b) : (x : Either a b) → Set where
done : ∀ {y} → Fuel f (Right y)
more : ∀ {x} → Fuel f (f x) → Fuel f (Left x)
tryFuel : (f : a → Either a b) (x : Either a b) (n : Nat) → Maybe (Fuel f x)
tryFuel f x zero = Nothing
tryFuel f (Left x) (suc n) = more <$> tryFuel f (f x) n
tryFuel f (Right y) (suc n) = Just done
getFuel : (f : a → Either a b) (x : Either a b) (n : Nat)
→ {IsJust (tryFuel f x n)} → Fuel f x
getFuel f x n {p} = fromJust (tryFuel f x n) {p}
module _ {a b : Set} where
loop : (f : a → Either a b) (x : a) → @0 Fuel f (Left x) → b
loop f x (more n) = go (f x) n
where
go : (x : Either a b) → @0 Fuel f x → b
go (Left x) (more n) = go (f x) n
go (Right y) done = y
{-# COMPILE AGDA2HS loop #-}