haskus-utils-variant-2.3: src/lib/Haskus/Utils/Variant/Cont.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ImplicitParams #-}
-- | Continuation based control-flow
module Haskus.Utils.Variant.Cont
( fret
, fretN
, freturn
, freturnN
, frec
-- * Control-flow
, fIf
, Then (..)
, Else (..)
)
where
import Haskus.Utils.Tuple
import Haskus.Utils.Types
import Haskus.Utils.Types.List
import Haskus.Utils.ContFlow
-- this define has to be defined in each module using ContFlow for now
#define fdo ContFlow $ \__cs -> let ?__cs = __cs in do
-- | Call the type-indexed continuation from the tuple passed as first parameter
fret :: forall x r t n xs.
( ExtractTuple n t (x -> r)
, xs ~ ContTupleToList t r
, CheckMember x xs
, n ~ IndexOf x xs
, KnownNat n
, CheckNub xs
) => t -> (x -> r)
{-# INLINE fret #-}
fret = tupleN @n @t @(x -> r)
-- | Implicitly call the type-indexed continuation in the context
freturn :: forall x r t n xs.
( ExtractTuple n t (x -> r)
, xs ~ ContTupleToList t r
, CheckMember x xs
, n ~ IndexOf x xs
, KnownNat n
, CheckNub xs
, ?__cs :: t
) => x -> r
{-# INLINE freturn #-}
freturn = fret ?__cs
-- | Call the indexed continuation from the tuple passed as first parameter
fretN :: forall n x r t xs.
( ExtractTuple n t (x -> r)
, xs ~ ContTupleToList t r
, x ~ Index n xs
, KnownNat n
) => t -> (x -> r)
{-# INLINE fretN #-}
fretN = tupleN @n @t @(x -> r)
-- | Implicitly call the type-indexed continuation in the context
freturnN :: forall n x r t xs.
( ExtractTuple n t (x -> r)
, xs ~ ContTupleToList t r
, x ~ Index n xs
, KnownNat n
, ?__cs :: t
) => x -> r
{-# INLINE freturnN #-}
freturnN = fretN @n ?__cs
-- | Recursive call
frec :: forall r xs.
( ?__cs :: ContListToTuple xs r
) => ContFlow xs r -> r
frec f = f >::> ?__cs
----------------------------------------
-- Control-flow
data Then = Then
data Else = Else
fIf :: Bool -> ContFlow '[Then,Else] r
{-# INLINE fIf #-}
fIf b = fdo
case b of
True -> freturn Then
False -> freturn Else