0

I was researching difference lists and found the DList type

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

and the function

dlToList :: DList a -> [a]
dlToList = ($[]) . unDL

I am wondering what is the non point free version of the function and what does ($[]) do?

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
G.G
  • 27
  • 4

1 Answers1

2

The first step in seeing into a point-free definition of a function is to revert the η-reduction:

dlToList = ($[]) . unDL
dlToList dl = (($[]) . unDL) dl

Then you start applying to the composition-chain, right-to-left:

dlToList dl = ($[]) (unDL dl)

You could then unpack the operator section

dlToList dl = unDL dl $ []

However, keeping the ($[]) as it is actually makes sense, because this is the essential converter between difference lists and ordinary lists: it takes a [a]->[a]-prepender-function and applies it to the terminator [], resulting in a concrete list.


We could simplify that further:
dlToList dl = unDL dl []

which, incidentally, could be made point-free again in a shorter manner:

dlToList = (`unDL`[])

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
  • Also can you explain me how does this works? `emptyDL :: DList a` `emptyDL = DL id` – G.G Apr 18 '16 at 20:55
  • The empty difference list is that list-prepending funcion which, when passed the (empty) terminator list, will just give that same list as the result. – leftaroundabout Apr 18 '16 at 20:59
  • But if we look at the types, `DL :: ([a] -> [a]) -> DList a` and `id :: a -> a` – G.G Apr 18 '16 at 22:24
  • Note that these polymorphic signatures are shorthand for _universally-quantified types_, i.e. really it should be `DL :: ∀a. ([a] -> [a]) -> DList a` and `id :: ∀a. a -> a`. Hence I might also write it as `id :: ∀b. b -> b`. And for any given type `A`, I can then substitute `b ~ [A]`. Got it? – leftaroundabout Apr 18 '16 at 23:23
  • This is clear now. I wasn't aware I can substitute `a ~ [A]. Thanks for that. – G.G Apr 18 '16 at 23:43