module Codata.IO where
open import Codata.IO.Core public
import IO.Primitive as Prim
open import Codata.IO.Types hiding (module FFI) public
open import Agda.Builtin.Unit
Main : Set
Main = Prim.IO ⊤
open import Level
open import Size
open import Codata.Thunk using (Thunk; force)
open import Agda.Builtin.Equality
open import Data.Maybe.Base using (Maybe)
open import Function
open import Foreign.Haskell.Coerce
private
variable
a b ℓ : Level
A : Set a
B : Set b
i : Size
map : {B : Set b} {{_ : b ≤ˡ ℓ}} → (A → B) → IO′ ℓ A i → IO′ ℓ B i
map f (lift m) = lift (m Prim.>>= λ a → Prim.return (f a))
map f (return a) = return (f a)
map f (bind m g) = bind m $ λ a → λ where .force → map f (g a .force)
delay : {A : Set a} {{_ : a ≤ˡ ℓ}} → Thunk (IO′ ℓ A) i → IO′ ℓ A i
delay m = bind m λ a → λ where .force → return a
infixr 1 _>>=_ _ᵗ>>=_ _>>=ᵗ_
_>>=_ : IO′ ℓ A i → (A → IO′ ℓ B i) → IO′ ℓ B i
m >>= f = bind (λ where .force → m) (λ a → λ where .force → f a)
_=<<_ : (A → IO′ ℓ B i) → IO′ ℓ A i → IO′ ℓ B i
f =<< m = m >>= f
_ᵗ>>=_ : Thunk (IO′ ℓ A) i → (A → IO′ ℓ B i) → IO′ ℓ B i
m ᵗ>>= f = bind m (λ a → λ where .force → f a)
_>>=ᵗ_ : IO′ ℓ A i → (A → Thunk (IO′ ℓ B) i) → IO′ ℓ B i
m >>=ᵗ f = bind (λ where .force → m) f
infixr 1 _>>_
infixl 1 _<<_ _<$_ _<$>_ _<*>_
_<$>_ : {B : Set b} {{_ : b ≤ˡ ℓ}} → (A → B) → IO′ ℓ A i → IO′ ℓ B i
f <$> m = m >>= λ a → return (f a)
_<$_ : {A : Set a} {{_ : a ≤ˡ ℓ}} → A → IO′ ℓ B i → IO′ ℓ A i
a <$ mb = mb >>= λ _ → return a
_<*>_ : {B : Set b} {{_ : b ≤ˡ ℓ}} → IO′ ℓ (A → B) i → IO′ ℓ A i → IO′ ℓ B i
f <*> m = f >>= (_<$> m)
_>>_ : ∀ {i} → IO′ ℓ A i → IO′ ℓ B i → IO′ ℓ B i
ma >> mb = ma >>= λ _ → mb
_<<_ : ∀ {i} {A : Set a} {{_ : a ≤ˡ ℓ}} → IO′ ℓ A i → IO′ ℓ B i → IO′ ℓ A i
ma << mb = ma >>= λ a → a <$ mb
module ListIO where
open import Data.List.Base as List using (List; []; _∷_)
sequence : {A : Set a} {{_ : a ≤ˡ ℓ}} →
List (IO ℓ A) → IO ℓ (List A)
sequence [] = return []
sequence (mx ∷ mxs) = mx >>= λ x →
sequence mxs >>= λ xs →
return (x ∷ xs)
module _ {B : Set b} {{_ : b ≤ˡ ℓ}} where
mapM : (A → IO ℓ B) → List A → IO ℓ (List B)
mapM f xs = sequence (List.map f xs)
mapM′ : (A → IO ℓ B) → List A → IO ℓ ⊤
mapM′ f xs = tt <$ mapM f xs
forM : List A → (A → IO ℓ B) → IO ℓ (List B)
forM = flip mapM
forM′ : List A → (A → IO ℓ B) → IO ℓ ⊤
forM′ = flip mapM′
module VecIO where
open import Data.Vec.Base as Vec using (Vec; []; _∷_)
sequence : ∀ {n} {A : Set a} {{_ : a ≤ˡ ℓ}} →
Vec (IO ℓ A) n → IO ℓ (Vec A n)
sequence [] = return []
sequence (mx ∷ mxs) = mx >>= λ x →
sequence mxs >>= λ xs →
return (x ∷ xs)
module _ {n} {B : Set b} {{_ : b ≤ˡ ℓ}} where
mapM : (A → IO ℓ B) → Vec A n → IO ℓ (Vec B n)
mapM f xs = sequence (Vec.map f xs)
mapM′ : (A → IO ℓ B) → Vec A n → IO ℓ ⊤
mapM′ f xs = tt <$ mapM f xs
forM : Vec A n → (A → IO ℓ B) → IO ℓ (Vec B n)
forM = flip mapM
forM′ : Vec A n → (A → IO ℓ B) → IO ℓ ⊤
forM′ = flip mapM′
module ColistIO where
open import Codata.Colist as Colist using (Colist; []; _∷_)
sequence : {A : Set a} {{_ : a ≤ˡ ℓ}} →
Colist (IO′ ℓ A i) ∞ → IO′ ℓ (Colist A ∞) i
sequence [] = return []
sequence (mx ∷ mxs) =
mx >>= λ x →
(λ where .force → sequence (mxs .force)) ᵗ>>= λ xs →
return (x ∷ λ where .force → xs)
module _ {B : Set b} {{_ : b ≤ˡ ℓ}} where
mapM : (A → IO′ ℓ B i) → Colist A ∞ → IO′ ℓ (Colist B ∞) i
mapM f xs = sequence (Colist.map f xs)
mapM′ : (A → IO′ ℓ B i) → Colist A ∞ → IO′ ℓ ⊤ i
mapM′ f xs = tt <$ mapM f xs
forM : Colist A ∞ → (A → IO′ ℓ B i) → IO′ ℓ (Colist B ∞) i
forM = flip mapM
forM′ : Colist A ∞ → (A → IO′ ℓ B i) → IO′ ℓ ⊤ i
forM′ = flip mapM′
open import Agda.Builtin.Char
open import Data.String
open import Codata.Musical.Costring
open import System.FilePath.Posix
import Codata.IO.Primitive as Prim
open import Codata.IO.Types
using ( BufferMode
; NoBuffering
; LineBuffering
; BlockBuffering
)
public
open import Codata.IO.Primitive
using ( Handle
; stdin
; stdout
; stderr
)
public
hSetBuffering : Handle → BufferMode → IO ℓ ⊤
hGetBuffering : Handle → IO ℓ BufferMode
hFlush : Handle → IO ℓ ⊤
interact : (String → String) → IO ℓ ⊤
getChar : IO ℓ Char
getLine : IO ℓ String
getContents : IO ℓ Costring
readFile : ∀ {n} → FilePath n → IO ℓ Costring
writeFile : ∀ {n} → FilePath n → Costring → IO ℓ ⊤
appendFile : ∀ {n} → FilePath n → Costring → IO ℓ ⊤
putChar : Char → IO ℓ ⊤
putCoStr : Costring → IO ℓ ⊤
putCoStrLn : Costring → IO ℓ ⊤
putStr : String → IO ℓ ⊤
putStrLn : String → IO ℓ ⊤
readFiniteFile : ∀ {n} → FilePath n → IO ℓ String
hSetBuffering h b = lift (coerce Prim.hSetBuffering h b)
hGetBuffering h = coerce <$> lift (Prim.hGetBuffering h)
hFlush = λ h → lift (Prim.hFlush h)
interact = λ f → lift (Prim.interact f)
getChar = lift Prim.getChar
getLine = lift Prim.getLine
getContents = lift Prim.getContents
readFile = λ fp → lift (Prim.readFile (getFilePath fp))
writeFile = λ fp cstr → lift (Prim.writeFile (getFilePath fp) cstr)
appendFile = λ fp cstr → lift (Prim.appendFile (getFilePath fp) cstr)
putChar = λ c → lift (Prim.putChar c)
putCoStr = λ cstr → lift (Prim.putStr cstr)
putCoStrLn = λ cstr → lift (Prim.putStrLn cstr)
putStr = putCoStr ∘′ toCostring
putStrLn = putCoStrLn ∘′ toCostring
readFiniteFile = lift ∘′ Prim.readFiniteFile ∘′ getFilePath
{-# NON_TERMINATING #-}
run : IO ℓ A → Prim.IO A
run (lift io) = io
run (return a) = Prim.return a
run (bind m f) = run (m .force) Prim.>>= λ a → run (f a .force)