I got'cher DList right here!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module Control.DList where

import Data.Monoid
import Control.Monad.Writer

infixr 5 |>
infixl 5 <|

{--

Your basic difference list, from Haskell to Idris, and back
This answers the Haskell exercise posed at http://lpaste.net/107593

 --}

data DList a = DL { unDL :: [a] -> [a] }

cons :: a -> [a] -> [a]
cons a list = a : list

(<|) :: DList a -> a -> DList a
dlist <| a = DL (unDL dlist . cons a)

(|>) :: a -> DList a -> DList a
a |> dlist = DL (cons a . unDL dlist)

emptyDL :: DList a
emptyDL = DL id

dlToList :: DList a -> [a]
dlToList dlist = unDL dlist []

-- added a fromList for difference lists to start from somewhere

dl :: [a] -> DList a
dl = DL . (++)

dl' :: a -> DList a -- your monadic return
dl' x = dl [x]

-- DLists are monoidal (perfect for writing to *cough* Writer *cough*)

instance Monoid (DList a) where
   mempty  = emptyDL
   d1 `mappend` d2 = DL (unDL d1 . unDL d2)

samp :: Writer (DList Char) () -- from Writer w a
samp = (\f twoB -> mapM_ f [twoB, " or not ", twoB]) (tell . dl) "to be"

-- *Control.DList> dlToList $ snd $ runWriter samp ~> "to be or not to be"

{--

Okay, so! What I'm not showing you here was there was an exercise where 
I was accumulating results as side-effects in the Writer log, but I had
an additional requirement that under certain conditions the log had to be
flushed, so that the results accumulated after the flush were the only
results (the results before being 'forgotten').

And DList allowed me to do that.

The problem facing me now is this: HOW DID I DO THAT?!? ;)

This, of course, is an exercise for the reader: create a writer monad such
that you write to the log, write to the log, write to the log, but, oop!
Flush the log now, all those recorded values are not needed. Now, write
to the log, write to the log, write to the log, and then get back your
(only three now) results.

--}