-- EDAF40
-- 1. type derivation (1.5p)
-- a.
elem :: (Eq a) => a -> [a] -> Bool
flip :: (a -> b -> c) -> b -> a -> c
not :: Bool -> Bool
filter :: (a -> Bool) -> [a] -> [a]
toLower :: Char -> Char
map :: (a -> b) -> [a] -> [b]
words :: String -> [String]
reduce :: a -> a
prepare = reduce . words . map toLower . filter (not . flip elem ".,:;*!#%&|")
--thus
elem :: a -> [a] -> Bool
flip elem :: [a] -> a -> Bool
flip elem ".,:;*!#%&|" :: Char -> Bool
(not . flip elem ".,:;*!#%&|") :: Char -> Bool
filter (not . flip elem ".,:;*!#%&|") :: [Char] -> [Char]
filter (not . flip elem ".,:;*!#%&|") :: String -> String
map toLower :: String -> String
map toLower . filter (not . flip elem ".,:;*!#%&|") :: String -> String
words . map toLower . filter (not . flip elem ".,:;*!#%&|") :: String -> [String]
reduce . words . map toLower . filter (not . flip elem ".,:;*!#%&|") :: String -> [String]
--thus
prepare :: String -> [String]
-- b.
map2 :: (a -> b, c -> d) -> (a, c) -> (b, d)
map :: (a -> b) -> [a] -> [b]
words :: String -> [String]
toLower :: Char -> Char
rulesCompile :: [(String, [String])] -> e
rulesCompile = (map . map2) (words . map toLower, map words)
--thus
map toLower :: String -> String
words . map toLower :: String -> [String]
map words :: [String] -> [[String]]
(words . map toLower, map words) :: (String -> [String] , [String] -> [[String]])
map2 :: (a -> b, c -> d) -> (a, c) -> (b, d)
map :: (a -> b) -> [a] -> [b]
map . map2 :: (a -> b, c -> d) -> [(a, c)] -> [(b, d)]
(map . map2) (words . map toLower, map words) :: [(String , [String])] -> [([String] , [[String]])]
-- thus e is
[( [String] , [[String]] )]
-- c.
transformationApply :: Eq a => a -> ([a] -> [a]) -> [a] -> ([a], [a]) -> Maybe [a]
orElse :: Maybe a -> Maybe a -> Maybe a
foldr1 :: (a -> a -> a) -> [ a ] -> a
-- thus
transformationApply :: a -> ([a] -> [a]) -> [a] -> ([a], [a]) -> Maybe [a]
transformationApply wildcard :: ([a] -> [a]) -> [a] -> ([a], [a]) -> Maybe [a]
transformationApply wildcard f :: [a] -> ([a], [a]) -> Maybe [a]
transformationApply wildcard f x :: ([a], [a]) -> Maybe [a]
(transformationApply wildcard f x) :: ([a], [a]) -> Maybe [a]
map (transformationApply wildcard f x) :: [ ([a], [a]) ] -> [ Maybe [a] ]
--thus
pats :: [ ([a], [a]) ]
(map (transformationApply wildcard f x) pats) :: [ Maybe [a] ]
foldr1 :: (a -> a -> a) -> [ a ] -> a
foldr1 orElse :: [ Maybe b ] -> Maybe b
-- putting it all together
foldr1 orElse (map (transformationApply wildcard f x) pats) :: Maybe [a]
-- 2. fib (1p)
k :: Num a => [a]
[0,1,1,2,3,5,8,13,21,34]
-- 3. altMap (1p)
altMap :: (a -> b) -> (a -> b) -> [a] -> [b]
altMap f g [] = []
altMap f g (x:[]) = [ f x ]
altMap f g (x:y:xs) = f x : g y : altMap f g xs
-- or
altmap f g [] = []
altmap f g (x:xs) = f x : altmap g f xs
-- 4. similScore (1p)
a. Version 1 is much faster than Version 2
b. because in version 1 the computation of simEntry i j is using the
tabularized values, while in version 2 it recursively attempts to
compute the value, without referring to earlier computations/table
positions.
-- 5. CircList (1.5p)
data CircList a = CircList [a] deriving Show
-- (deriving not necessary for getting full points)
perimeter (CircList l) = length l
currentelem (CircList l) = listToMaybe l
nextelem (CircList []) = Nothing
nextelem (CircList [a]) = Just a
nextelem (CircList (x:xs))= listToMaybe xs
previouselem (CircList []) = Nothing
previouselem (CircList [a]) = Just a
previouselem (CircList (x:xs)) = listToMaybe $ reverse xs
insert x (CircList a) = CircList $ (a++[x])
delete n (CircList l)
| perimeter (CircList l) <= n = CircList []
| otherwise = CircList $ drop n l
takefromCL n (CircList []) = []
takefromCL n (CircList l) = take n $ cycle l
-- extra points for noticing (Eq a) requirement!
equalCL (CircList xs) (CircList ys)
| length xs /= length ys = False
| null xs = True
| otherwise = or $ map (xs==) (permutations ys)
permutations xs = take (length xs) (iterate rotate xs)
rotate [] = []
rotate (x:xs) = xs++[x]
-------------------------------------------------------------------
EDAN40
-- 1
instance Num MyNatural where
(+) = f1
(-) = f3
(*) = f2
negate Empty = Empty
negate _ = error "no negative naturals exist"
abs = id
signum Empty = Empty
signum _ = () :-: Empty
fromInteger n
| n < 0 = error "no negative naturals exist"
| n == 0 = Empty
| otherwise = () :-: fromInteger (n-1)
--2
-- see 4 in EDAF40 above
-- 3
-- a.
g :: (a -> a) -> (a -> Maybe (a,a))
-- b.
g f x = Just (x, f x)
-- 4
"our" fmap reverts the argument list, thus composition diagram won't commute:
-- a counterexample
let p be (+1)
let q be (*2)
let x be [1,2,3]
p . q = (+1) . (*2)
fmap (p . q) x = [7, 5, 3]
fmap (*2) x = [6, 4, 2]
fmap (+1) [6, 4, 2] = [3, 5, 7]
-- so
fmap (p . q) != (fmap p) . (fmap q)
-- 5
spark: "potential of a thread"
seq: forces evaluation its first argument up to WHNF, has value of the second argument
pseq: forces evaluation its first argument up to WHNF **before** returning value of the second argument
par: evaluates its first argument up to WHNF, possibly in parallel (creates a spark) with returning value of the second argument
-- 6
-- a
(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
-- b
see in EDAF40 above
-- c
see in EDAF40 above