PPL 2020.07.17 Ex 1 - Scheme Define the verbose construct for folding illustrated by the following example: (cobol-fold direction -> from 1 data 1 2 3 4 5 6 (exec (displayln y) (+ x y)) using x y) This is a fold-right (->) with initial value 1 on the list (1 2 3 4 5 6), and the fold function is given in the "exec" part. Of course, <- is used to select fold-left instead of right. Ex 2 - Haskell Define a data type that stores an m by n matrix as a list of lists by row. After defining an appropriate data constructor, do the following: 1. Define a function `new' that takes as input two integers m and n and a value `fill', and returns an m by n matrix whose elements are all equal to `fill'. 2. Define function `replace' such that, given a matrix m, the indices i, j of one of its elements, and a new element, it returns a new matrix equal to m except for the element in position i, j, which is replaced with the new one. 3. Define function `lookup', which returns the element in a given position of a matrix. 4. Make the data type an instance of Functor and Foldable. 5. Make the data type an instance of Applicative. In your implementation you can use the following functions: splitAt :: Int -> [a] -> ([a], [a]) unzip :: [(a, b)] -> ([a], [b]) (!!) :: [a] -> Int -> a Ex 3 - Erlang Define a "broadcaster" process which answers to the following commands: - {spawn, L, V} creates a process for each element of L, passing its initial parameter in V, where L is a list of names of functions defined in the current module and V is their respective parameters (of course it must be |L| = |V|); - {send, V}, with V a list of values, sends to each respective process created with the previous spawn command a message in V; e.g. {spawn, [1,2,3]} will send 1 to the first process, 2 to the second, and 3 to the third; - stop is used to end the broadcaster, and to also stop every process spawned by it. SOLUTIONS Ex 1 (define-syntax cobol-fold (syntax-rules (direction -> <- data using from exec) ((_ direction -> from i data d ... (exec e ... ) using x y) (foldr (lambda (x y) e ...) i '(d ...))) ((_ direction <- from i data d ... (exec e ... ) using x y) (foldl (lambda (x y) e ...) i '(d ...))))) Ex 2 newtype Matrix a = Matrix [[a]] deriving (Eq, Show) new :: Int -> Int -> a -> Matrix a new m n fill = Matrix [[fill | _ <- [1..n]] | _ <- [1..m]] replace :: Int -> Int -> a -> Matrix a -> Matrix a replace i j x (Matrix rows) = let (rowsHead, r:rowsTail) = splitAt i rows (rHead, x':rTail) = splitAt j r in Matrix $ rowsHead ++ ((rHead ++ (x:rTail)):rowsTail) lookup :: Int -> Int -> Matrix a -> a lookup i j (Matrix rows) = (rows !! i) !! j instance Functor Matrix where fmap f (Matrix rows) = Matrix $ map (\r -> map f r) rows instance Foldable Matrix where foldr f e (Matrix rows) = foldr (\r acc -> foldr f acc r) e rows hConcat :: Matrix a -> Matrix a -> Matrix a hConcat (Matrix []) m2 = m2 hConcat m1 (Matrix []) = m1 hConcat (Matrix (r1:r1s)) (Matrix (r2:r2s)) = let (Matrix tail) = hConcat (Matrix r1s) (Matrix r2s) in Matrix $ (r1 ++ r2) : tail vConcat :: Matrix a -> Matrix a -> Matrix a vConcat (Matrix rows1) (Matrix rows2) = Matrix $ rows1 ++ rows2 concatMapM :: (a -> Matrix b) -> Matrix a -> Matrix b concatMapM f (Matrix rows) = let empty = Matrix [] in foldl (\acc r -> vConcat acc $ foldl (\acc x -> hConcat acc (f x)) empty r) empty rows instance Applicative Matrix where pure x = Matrix [[x]] fs <*> xs = concatMapM (\f -> fmap f xs) fs Ex 3 broadcaster(Pids) -> receive {spawn, Fs, Vs} -> FDs = lists:zip(Fs, Vs), io:format("~p~n", [FDs]), broadcaster([spawn_link(?MODULE, F, V) || {F,V} <- FDs]); {send, Vs} -> FDs = lists:zip(Pids, Vs), io:format("~p~n", [FDs]), [ Pid ! V || {Pid, V} <- FDs]; stop -> ok end.