--
{-# Language DeriveFunctor, FlexibleInstances #-}
module HW5 where
import Control.Arrow( Arrow, ArrowChoice, ArrowLoop, Kleisli(..)
, arr, first, second, (***), (&&&)
, left, right, (+++), (|||)
, loop )
import Control.Category(Category, (>>>), (.), id)
import Control.Monad(liftM)
import Prelude hiding((.), id)
import Data.Char(ord,chr,digitToInt)
-----------------------------------------------------
-- Part 1. Programming with Arrows
-----------------------------------------------------
-- Arrow type signatures for reference.
{-
first :: Arrow a => a b c -> a (b, d) (c, d)
second :: Arrow a => a b c -> a (d, b) (d, c)
(***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
(&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
left :: ArrowChoice a => a b c -> a (Either b d) (Either c d)
right :: ArrowChoice a => a b c -> a (Either d b) (Either d c)
(+++) :: ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c')
(|||) :: ArrowChoice a => a b d -> a c d -> a (Either b c) d
-}
------------------------------------------------------
-------------------------------------------------
-- Question #1
-- Write strToInteger using arrows
-- test your code
-- use the following guide
-- "4385"::Int -->
-- ([4,3,8,5],[0,1,2,3])::([Int],[Integer]) -->
-- ([4,3,8,5],[0,1,2,3])::([Integer],[Integer]) -->
-- ([5,8,3,4],[1,10,100,1000])::([Integer],[Integer]) -->
-- [5,80,300,4000]::[Integer] -->
-- 4385::Integer
strToInteger :: [Char] -> Integer
strToInteger = undefined
-------------------------------------------------------
-- Question #2
-- Write the function printFileInc using arrows
-- I reads a string of digits from a file, and prints to the terminal
-- the successor of the value of that string of digits as an Integer .
-- Test your code.
printFileInc :: Kleisli IO FilePath ()
printFileInc = undefined
-------------------------------------------------------
-- Question #3
-- Write the function incFile using arrows.
-- It reads a string of digits from a file, and prints
-- the successor of the value of that string of digits
-- to another file.
-- Test your code.
incFile:: FilePath -> FilePath -> IO ()
incFile s t = undefined
--------------------------------------------------------
-- Part 2, Programming with Algebras
--------------------------------------------------------
-- Some Functors
data F1 x = Zero | One | Plus x x deriving Functor
data ListF a x = Nil | Cons a x deriving Functor
data StreamF n x = C n x deriving Functor
data NatF x = Z | S x deriving Functor
-----------------------------------------
-- Algebras and their duals co-Algebras
data Algebra f c = Algebra (f c -> c)
data CoAlgebra f c = CoAlgebra {unCoAlgebra:: c -> f c }
--------------------------------------------
-- Initial and Final Algebras
data Initial f = Init (f (Initial f))
data Final f = Final{ unFinal:: (f (Final f)) }
--------------------------------------------
-- Operations on Initial (cata) and Final (ana) algebras
cata :: Functor f => (Algebra f b) -> Initial f -> b
cata (Algebra phi) (Init x) = phi(fmap (cata (Algebra phi)) x)
ana :: Functor f => (CoAlgebra f seed) -> seed -> (Final f)
ana (CoAlgebra phi) seed = Final(fmap (ana (CoAlgebra phi)) (phi seed))
-----------------------------------------------------------
-- Stating Proofs about Algebras and thir operations
data Arrow f a b = Arr (Algebra f a) (Algebra f b) (a->b)
-- For every Arrow (Arr (Algebra f) (Algebra g) h) it must be the case that
--
-- F a ---- fmap h -----> F b
-- | |
-- | f | g
-- | |
-- V V
-- a -------- h --------> b
valid :: (Eq b, Functor f) => HW5.Arrow f a b -> f a -> Bool
valid (Arr (Algebra f) (Algebra g) h) x = h(f x) == g(fmap h x)
data CoHom f a b = CoHom (CoAlgebra f a) (CoAlgebra f b) (a->b)
-- For every arrow in the category
-- (CoHom (CoAlgebra f) (CoAlgebra g) h) it must be the case that
--
-- F a ---- fmap h -----> F b
-- ^ ^
-- | |
-- | f | g
-- | |
-- a -------- h --------> b
covalid :: (Eq (f b), Functor f) => CoHom f a b -> a -> Bool
covalid (CoHom (CoAlgebra f) (CoAlgebra g) h) x = fmap h (f x) == g(h x)
--------------------------------------------------------------------
-- Question #4
data TreeF x = X x -- Finsh these by replacing "X x" to the right of the =
data LangF x = Y x
-------------------------------------------
-- Question #5
n1 :: Initial NatF
n1 = undefined
l1 :: Initial (ListF Int)
l1 = undefined
t1 :: Initial TreeF
t1 = undefined
e1 :: Initial LangF
e1 = undefined
-----------------------------------------------------
-- Question #6
instance Show a => Show (Initial (ListF a)) where
show x = undefined
instance Show (Initial LangF ) where
show x = undefined
add :: Initial NatF -> Initial NatF -> Initial NatF
add x = undefined
data Store s x = St(s -> (x,s))
type Map = [(String,Value)]
type Value = Int
eval5a :: Iniitia LangF -> Store Map Value
eval5a x = undefined
-------------------------------------------------------
-- Question # 7
infExp :: Final LangF
infExp = undefined
-------------------------------------------------------
-- Question 8
prefix:: Int -> Final LangF -> Initial LangF
prefix n (Final x) = undefined
--