module UVMHS.Core.Data.Function where

import UVMHS.Core.Init
import UVMHS.Core.Classes

instance Functor (() r) where 
  map :: forall a b. (a -> b) -> (r -> a) -> r -> b
map a -> b
f r -> a
g = a -> b
f (a -> b) -> (r -> a) -> r -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
 r -> a
g
instance Return (() r) where 
  return :: forall a. a -> r -> a
return = a -> r -> a
forall a b. a -> b -> a
const
instance Bind (() r) where 
  r -> a
f ≫= :: forall a b. (r -> a) -> (a -> r -> b) -> r -> b
≫= a -> r -> b
k = \ r
r  a -> r -> b
k (r -> a
f r
r) r
r
instance Monad (() r)

instance (Null a)  Null (r  a) where
  null :: r -> a
null = a -> r -> a
forall a b. a -> b -> a
const a
forall a. Null a => a
null
instance (Append a)  Append (r  a) where
  r -> a
f ⧺ :: (r -> a) -> (r -> a) -> r -> a
 r -> a
g = \ r
r  r -> a
f r
r a -> a -> a
forall a. Append a => a -> a -> a
 r -> a
g r
r
instance (Monoid a)  Monoid (r  a)

instance (Eq a)  Eq (()  a) where
  () -> a
f == :: (() -> a) -> (() -> a) -> Bool
== () -> a
g = () -> a
f () a -> a -> Bool
forall a. Eq a => a -> a -> Bool
 () -> a
g ()
instance (Ord a)  Ord (()  a) where
  compare :: (() -> a) -> (() -> a) -> Ordering
compare () -> a
f () -> a
g = () -> a
f () a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
 () -> a
g ()
instance (Show a)  Show (()  a) where
  show :: (() -> a) -> String
show = a -> String
forall a. Show a => a -> String
show (a -> String) -> ((() -> a) -> a) -> (() -> a) -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
 () -> (() -> a) -> a
forall a b. a -> (a -> b) -> b
appto ()

pipe  (a  b)  (b  c)  a  c
pipe :: forall a b c. (a -> b) -> (b -> c) -> a -> c
pipe = ((b -> c) -> (a -> b) -> a -> c) -> (a -> b) -> (b -> c) -> a -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(∘)

iterateWith  (a  𝑂 a)  a  a
iterateWith :: forall a. (a -> 𝑂 a) -> a -> a
iterateWith a -> 𝑂 a
f = 
  let loop' :: a -> a
loop' a
x = case a -> 𝑂 a
f a
x of
        𝑂 a
None  a
x
        Some a
x'  a -> a
loop' a
x'
  in a -> a
loop'

iterateFrom  a  (a  𝑂 a)  a
iterateFrom :: forall a. a -> (a -> 𝑂 a) -> a
iterateFrom = ((a -> 𝑂 a) -> a -> a) -> a -> (a -> 𝑂 a) -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> 𝑂 a) -> a -> a
forall a. (a -> 𝑂 a) -> a -> a
iterateWith