summaryrefslogtreecommitdiff
path: root/lec07/JoinList.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lec07/JoinList.hs')
-rw-r--r--lec07/JoinList.hs48
1 files changed, 48 insertions, 0 deletions
diff --git a/lec07/JoinList.hs b/lec07/JoinList.hs
index 4726de2..7f626df 100644
--- a/lec07/JoinList.hs
+++ b/lec07/JoinList.hs
@@ -5,6 +5,8 @@ import Buffer
import Scrabble
import Sized
+import Data.List
+
data JoinList m a = Empty
| Single m a
| Append m (JoinList m a) (JoinList m a)
@@ -58,3 +60,49 @@ takeJ n jl@(Append m jl1 jl2)
where
s1 = getSize $ size $ tag jl1
m' = getSize $ size m
+
+-- Exercise 4
+
+-- fold for join-lists
+foldJ :: b -> (a -> b) -> (b -> b -> b) -> JoinList m a -> b
+foldJ i _ _ Empty = i
+foldJ _ f _ (Single _ a) = f a
+foldJ i f g (Append _ jl1 jl2) = g (foldJ i f g jl1) (foldJ i f g jl2)
+
+-- From a list, make a join-list that satisfies the properties of indexJ, takeJ,
+-- and dropJ, with an additional function that calculates each annotation.
+-- This function builds a join-list that has the most balanced branches.
+makeJ :: Monoid m => (a -> m) -> [a] -> JoinList m a
+makeJ _ [] = Empty
+makeJ f [a] = Single (f a) a
+makeJ f ls = (makeJ f $ dt ls 0 h) +++ (makeJ f $ dt ls h (l-h))
+ where
+ l = length ls
+ h = l `div` 2
+ dt ls x y = take y $ drop x ls
+
+instance Buffer (JoinList (Score, Size) String) where
+ toString jl = foldJ "" id (\x y -> x ++ y) jl
+
+ fromString s = makeJ (\x -> (scoreString x, Size 1)) $ lines s
+
+ line = indexJ
+
+ replaceLine n ln jl = (takeJ (n-1) jl) +++ (Single (scoreString ln, 1) ln) +++ (dropJ n jl)
+
+ numLines = foldJ 0 (\_ -> 1) (\x y -> x + y)
+
+ value jl = getScore $ foldJ 0 (\s -> scoreString s) (\x y -> x <> y) jl
+ where getScore (Score s) = s
+
+initialLines :: [String]
+initialLines =
+ "This is the first line.\n" ++
+ "Then this, which is the second line.\n" ++
+ "As you might've guessed, this is the third.\n"
+
+initialContent :: JoinList (Score, Size) String
+initialContent = fromString initialLines
+
+main = runEditor editor $ initialContent
+-- error: No instance for ‘Applicative (Editor b)’ arising from the 'deriving' clause of a data type declaration