Haskell - help understanding a function - list

I have this mystery function that I'm having trouble understanding:
mystery :: [a] -> [[a]]
mystery [] = [[]]
mystery (x:xs) = sets ++ (map (x:) sets)
where sets = mystery xs
Here are some inputs with results:
mystery [1,2] returns [[],[2],[1],[1,2]]
mystery [1,2,3] returns [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]
By looking at the results I can see that its computing all the possible combinations of the numbers in the list, but not all the possible permuations...I think.
The trouble i'm having is actually going through the recursion and understanding how the function is getting those results.
I think I get the start of it --> mapping (1:) onto [2], yielding [1,2], but its at this point that I'm confused how the recursion works, and whether I'm still mapping (1:) or now (2:), and onto what exactly.
If anyone could please help me out by explaining step by step (using one of the examples provided) how this function works (with the map and sets recursion), that would be greatly appreciated!
Thank you!

Haskell will perform what is known as lazy evaluation, meaning it will only work things out as it needs them from left to right (generally). So taking your example of mystery [1, 2], Haskell will do the following:
sets ++ (map (x:) sets)
Which evaluates to:
mystery (2:[]) ++ (map (1:) sets)
At this point, we're calling mystery (2:[])
mystery ([]) ++ (map (2:) sets) ++ (map (1:) sets)
mystery ([]) will return an empty list of lists
[[]] ++ (map (2:) sets) ++ (map (1:) sets)
[[]] ++ (map (2:) mystery []) ++ (map (1:) sets)
So now Haskell will try to apply the function (2:) on a list containing an empty list
[[]] ++ (2:[[]]) ++ (map (1:) sets)
[[]] ++ [[2]] ++ (map (1:) sets)
[[], [2]] ++ (map (1:) sets)
This is where things get a little more confusing.
[[], [2]] ++ (map (1:) mystery (2:[]))
That last sets will evaluate mystery (2:[])
[[], [2]] ++ (map (1:) (sets ++ (map (2:) sets)))
[[], [2]] ++ (map (1:) (mystery [] ++ (map (2:) sets))
[[], [2]] ++ (map (1:) ([[]] ++ (map (2:) mystery []))
[[], [2]] ++ (map (1:) ([[]] ++ (2:[[]]))
[[], [2]] ++ (map (1:) ([[]] ++ [[2]])
Now (1:) will be applied to a list which contains an empty list, and a list containing the 2:
[[], [2]] ++ (map (1:) ++ [[], [2]])
[[], [2]] ++ [[1], [1, 2]]
[[], [2], [1], [1, 2]]
The real meat of the operation is in those last two sections. Haskell creates a list like [[], [2]] and then appends one to the head of each list to form [[1], [1, 2]].

your mystery function is computes the power set of its input.

Related

How to fix the error ('cannot construct the infinite type') in my code and how to make my code work

Basically i'm trying to do a function where you are given a list and a number and you have to split the list in lists of the same size as the number given and the last split of all can have a length lower than the number given
separa a xs = if length xs >= a then separaM a (drop a xs) ([take a xs]) else [xs]
separaM a xs yss = if length xs >= a then separaM a (drop a xs) (yss : (take a xs)) else separaM a [] (yss : xs)
separaM a [] yss = yss
I expect the output of 3 "comovais" to be ["com","ova","is"] but in my program there is no output because of the error
Note that the expression:
yss : (take a xs)
(take a xs) has type [b], so yss has type b. But when you pass yss : (take a xs) as an argument to separaM function, yss is expected has type [b] not b. That is why the error occurred.
Actually, you don't need yss to store the result, the recursive function can be defined as:
separaM _ [] = []
separaM a xs = (if length xs >= a then (take a xs) else xs) :
separaM a (drop a xs)
Your code has some errors in it. Tweaking your misuse of (:) gets it to pass the type-checker:
separa a xs
| length xs >= a = go a (drop a xs) [take a xs]
| otherwise = [xs]
where
go a xs yss
| length xs >= a = go a (drop a xs) (yss ++ [take a xs])
-- was: (yss : (take a xs))
| otherwise = go a [] (yss ++ [xs])
-- was: (yss : xs)
go a [] yss = yss
but it's better to further change it to
separa :: Int -> [a] -> [[a]]
separa a xs
| length xs >= a = go a (drop a xs) [take a xs]
| otherwise = [xs]
where
go a xs yss
| length xs >= a = go a (drop a xs) ([take a xs] ++ yss)
| otherwise = reverse ([xs] ++ yss)
It works:
> separa 3 [1..10]
[[1,2,3],[4,5,6],[7,8,9],[10]]
This is a common "build in reverse, then reverse when built" idiom, frequently seen in strict functional languages. Some of them allow for lists to be built in top-down, natural order, by a technique known as tail-recursion modulo cons. Haskell is lazy, and lets us build its lists in top-down manner naturally and easily, with the equivalent guarded recursion:
separa :: Int -> [a] -> [[a]]
separa a xs
| length xs >= a = go a (drop a xs) [take a xs]
| otherwise = [xs]
where
go a xs yss
| length xs >= a = -- go a (drop a xs) (yss ++ [take a xs])
yss ++ go a (drop a xs) [take a xs]
| otherwise = -- go a [] (yss ++ [xs])
yss ++ [xs]
There's an off-by-one error here; I'll leave it for you to fix on your own.
But sometimes the infinite type is inherent to a problem, and not a result of a programming error. Then we can fix it by using recursive types.
Whenever we get type equivalency t ~ a..b..t..c.., we can start by defining a type
newtype T = MkT (a..b..T..c..)
then see which type variables are free and close over them, as
newtype T a b c = MkT (a..b..(T a b c)..c..)
An example: Infinite type error when defining zip with foldr only; can it be fixed?

Defining inits function recursively

In Data.List module there's inits function that turns for example, [1,2,3,4] -> [[],[1],[1,2],[1,2,3],[1,2,3,4]]
I'm trying to define similar function using recursion, however I can't think of a way doing in correct order. The closest I have gotten is the list backwards, result = [[],[4],[3,4],[2,3,4],[1,2,3,4]]:
inits' :: [Int] -> [[Int]]
inits' [] = [[]]
inits' (x:xs) = inits' xs ++ [(x:xs)]
I'm not exactly sure how I could create a list by appending one element at time in the correct order? Could someone point in right direction, or is it not possible to do via recursion?
The easiest thing to try for such a function is just looking at the desired result and “reverse-pattern-matching” on the RHS of the function equation.
You already have that with
inits' [] = [[]]
Now with inits (x:xs), for example inits (1:[2,3,4]), you know that the result should be [[],[1],[1,2],[1,2,3],[1,2,3,4]], which matches the pattern []:_. So
inits' (x:xs) = [] : _
Now, the simplest recursion would be to just call inits' again on xs, like
inits' (x:xs) = [] : inits' xs
however, that doesn't give the correct result: assuming the recursive call works correctly, you have
inits' (1:[2,3,4]) = [] : [[],[2],[2,3],[2,3,4]]
= [[],[],[2],[2,3],[2,3,4]]
The 1 is completely missing, obviously, because we didn't actually use it in the definition. We need to use it, in fact it should be prepended before all of the list-chunks in the recursive result. You can do that with map.
We can prepend the data of all the remaining inits, like for example:
inits' :: [a] -> [[a]]
inits' [] = [[]]
inits' (x:xs) = [] : map (x:) (inits' xs)
As a basecase we return a singleton list with an empty list when the input is an empty list.
In the recursive case, we first yield the empty list, followed by the inits' of the tail of the list, but all these elements are prepended with x (with map (x:)).
Then we have:
Prelude> inits' [1,4,2,5]
[[],[1],[1,4],[1,4,2],[1,4,2,5]]
Since (not in evaluation order):
inits' [1,4,2,5]
-> [] : map (1:) (inits' [4,2,5])
-> [] : map (1:) ([] : map (4:) (inits' [2,5]))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) (inits' [5])))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) ([] : map (5:) (inits' []))))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) ([] : map (5:) [[]])))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) ([] : [[5]])))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) [[],[5]]))
-> [] : map (1:) ([] : map (4:) ([] : [[2],[2,5]]))
-> [] : map (1:) ([] : map (4:) [[],[2],[2,5]])
-> [] : map (1:) ([] : [[4],[4,2],[4,2,5]])
-> [] : map (1:) [[],[4],[4,2],[4,2,5]]
-> [] : [[1],[1,4],[1,4,2],[1,4,2,5]]
-> [[],[1],[1,4],[1,4,2],[1,4,2,5]]
I think you should change your function definition from:
inits' :: [Int] -> [[Int]]
to:
inits' :: [a] -> [[a]]
Since inits from Data.List is of type [a] -> [[a]], and it doesn't care whats actually in the list. It needs to be polymorphic and accept a list of any type.
Furthermore, since others have shown the most straightforward recursive approach, you can also use foldr here.
Here is the base code:
inits' :: [a] -> [[a]]
inits' = foldr (\x acc -> [] : (map (x:) acc)) [[]]
Where [[]] is the base case, just like in your function. For the actual recursive part, here is how it works with the call inits' [1, 2, 3, 4]:
Starts folding from the right at value 4, and creates [[], [4]]
Now on value 3, and creates [[], [3], [3, 4]
Now on value 2, and creates [[], [2], [2, 3], [2, 3, 4]]
Now on value 1, and creates [[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
Which gives the final nested list required, similarily to the function call:
*Main> inits' [1,2,3,4]
[[],[1],[1,2],[1,2,3],[1,2,3,4]]
From the behavior described above, you just need to focus on [] : (map (x:) acc), where you map the current value x being folded into your accumulated list acc, while also prepending an empty list on each fold.
If you still have trouble understanding foldr, you can look at this minimal example of how the folding performs from the right:
foldr f x [a, b, c] = a `f` (b `f` (c `f` x))
and How does foldr work?

Haskell: wrap everything in list of lists as a list of lists of one element

Good day everyone.
What I am trying to accomplish is to convert a list like
[ [1, 2, 3], [25, 24, 23, 22], [13] ] into [ [1], [2], [3], [25], [24], [23], [22], [13] ].
I tried something like
reWrap :: [[a]] -> [[a]]
reWrap data = map (map (:[])) data
but of course it just wrapped the contents even deeper into brackets. I'm new into functional programming so any help or tip would be much appreciated. Thank you in advance!
This is clearly a case for good old list comprehension:
rewrap xss = [ [x] | xs <- xss, x <- xs ]
This is quite easy, if you use the concatMap prelude function:
λ> :t concatMap
concatMap :: (a -> [b]) -> [a] -> [b]
What concatMap does is map a function, then concat the resulting lists.
If we use this definition, we can get the desired effect:
solution :: [[a]] -> [[a]]
solution = concatMap (map (:[]))
Here it is in action:
λ> solution [[1,2,3],[4,5,6]]
[[1],[2],[3],[4],[5],[6]]
λ> solution [[1,2,3],[],[12,19]]
[[1],[2],[3],[12],[19]]
As #amalloy said, the >>= function in the case of lists is equivalent to flip concatMap, so you could say this:
solution = (=<<) (map (:[]))
first you need to concat the list
this [ [1, 2, 3], [25, 24, 23, 22], [13] ]
becomes [1,2,3,25,24,23,22,13]
then you need to wrap each element in a list
reWrap = map (:[]) . concat
Perhaps reWrap = (>>= map return)? But this is probably too abstruse for a beginner. There is a solution very close to the one you were trying: rewrap xs = concat $ map (map (:[])) xs. Note that your output was very close to what you wanted, except that everything was exactly one level too deep in a list; concat takes a list of lists and flattens it.
My solution is really doing the same thing, just with more shorthand. Specifically, (:[]) is just return specialized to lists, and concat $ map f xs is the same as xs >>= f for lists. Then I also removed the explicit xs argument, since all you do with it is pass it to the partially-applied function you're really defining.
A recursive version, not the shortest, yet that illustrates the wrapping of each item in each nested list, and that concatenates wrapped nested lists,
reWrap :: [[a]] -> [[a]]
reWrap [] = [[]]
reWrap (xs:xss) = (map (:[]) xs) ++ reWrap xss

What does this list permutations implementation in Haskell exactly do?

I am studying the code in the Data.List module and can't exactly wrap my head around this implementation of permutations:
permutations :: [a] -> [[a]]
permutations xs0 = xs0 : perms xs0 []
where
perms [] _ = []
perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is)
where interleave xs r = let (_,zs) = interleave' id xs r in zs
interleave' _ [] r = (ts, r)
interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r
in (y:us, f (t:y:us) : zs)
Can somebody explain in detail how these nested functions connect/work with each other?
Sorry about the late answer, it took a bit longer to write down than expected.
So, first of all to maximize lazyness in a list function like this there are two goals:
Produce as many answers as possible before inspecting the next element of the input list
The answers themselves must be lazy, and so there the same must hold.
Now consider the permutation function. Here maximal lazyness means:
We should determine that there are at least n! permutations after inspecting just n elements of input
For each of these n! permutations, the first n elements should depend only on the first n elements of the input.
The first condition could be formalized as
length (take (factorial n) $ permutations ([1..n] ++ undefined))) `seq` () == ()
David Benbennick formalized the second condition as
map (take n) (take (factorial n) $ permutations [1..]) == permutations [1..n]
Combined, we have
map (take n) (take (factorial n) $ permutations ([1..n] ++ undefined)) == permutations [1..n]
Let's start with some simple cases. First permutation [1..]. We must have
permutations [1..] = [1,???] : ???
And with two elements we must have
permutations [1..] = [1,2,???] : [2,1,???] : ???
Note that there is no choice about the order of the first two elements, we can't put [2,1,...] first, since we already decided that the first permutation must start with 1. It should be clear by now that the first element of permutations xs must be equal to xs itself.
Now on to the implementation.
First of all, there are two different ways to make all permutations of a list:
Selection style: keep picking elements from the list until there are none left
permutations [] = [[]]
permutations xxs = [(y:ys) | (y,xs) <- picks xxs, ys <- permutations xs]
where
picks (x:xs) = (x,xs) : [(y,x:ys) | (y,ys) <- picks xs]
Insertion style: insert or interleave each element in all possible places
permutations [] = [[]]
permutations (x:xs) = [y | p <- permutations xs, y <- interleave p]
where
interleave [] = [[x]]
interleave (y:ys) = (x:y:ys) : map (y:) (interleave ys)
Note that neither of these is maximally lazy. The first case, the first thing this function does is pick the first element from the entire list, which is not lazy at all. In the second case we need the permutations of the tail before we can make any permutation.
To start, note that interleave can be made more lazy. The first element of interleave yss list is [x] if yss=[] or (x:y:ys) if yss=y:ys. But both of these are the same as x:yss, so we can write
interleave yss = (x:yss) : interleave' yss
interleave' [] = []
interleave' (y:ys) = map (y:) (interleave ys)
The implementation in Data.List continues on this idea, but uses a few more tricks.
It is perhaps easiest to go through the mailing list discussion. We start with David Benbennick's version, which is the same as the one I wrote above (without the lazy interleave). We already know that the first elment of permutations xs should be xs itself. So, let's put that in
permutations xxs = xxs : permutations' xxs
permutations' [] = []
permutations' (x:xs) = tail $ concatMap interleave $ permutations xs
where interleave = ..
The call to tail is of course not very nice. But if we inline the definitions of permutations and interleave we get
permutations' (x:xs)
= tail $ concatMap interleave $ permutations xs
= tail $ interleave xs ++ concatMap interleave (permutations' xs)
= tail $ (x:xs) : interleave' xs ++ concatMap interleave (permutations' xs)
= interleave' xs ++ concatMap interleave (permutations' xs)
Now we have
permutations xxs = xxs : permutations' xxs
permutations' [] = []
permutations' (x:xs) = interleave' xs ++ concatMap interleave (permutations' xs)
where
interleave yss = (x:yss) : interleave' yss
interleave' [] = []
interleave' (y:ys) = map (y:) (interleave ys)
The next step is optimization. An important target would be to eliminate the (++) calls in interleave. This is not so easy, because of the last line, map (y:) (interleave ys). We can't immediately use the foldr/ShowS trick of passing the tail as a parameter. The way out is to get rid of the map. If we pass a parameter f as the function that has to be mapped over the result at the end, we get
permutations' (x:xs) = interleave' id xs ++ concatMap (interleave id) (permutations' xs)
where
interleave f yss = f (x:yss) : interleave' f yss
interleave' f [] = []
interleave' f (y:ys) = interleave (f . (y:)) ys
Now we can pass in the tail,
permutations' (x:xs) = interleave' id xs $ foldr (interleave id) [] (permutations' xs)
where
interleave f yss r = f (x:yss) : interleave' f yss r
interleave' f [] r = r
interleave' f (y:ys) r = interleave (f . (y:)) ys r
This is starting to look like the one in Data.List, but it is not the same yet. In particular, it is not as lazy as it could be.
Let's try it out:
*Main> let n = 4
*Main> map (take n) (take (factorial n) $ permutations ([1..n] ++ undefined))
[[1,2,3,4],[2,1,3,4],[2,3,1,4],[2,3,4,1]*** Exception: Prelude.undefined
Uh oh, only the first n elements are correct, not the first factorial n.
The reason is that we still try to place the first element (the 1 in the above example) in all possible locations before trying anything else.
Yitzchak Gale came up with a solution. Considered all ways to split the input into an initial part, a middle element, and a tail:
[1..n] == [] ++ 1 : [2..n]
== [1] ++ 2 : [3..n]
== [1,2] ++ 3 : [4..n]
If you haven't seen the trick to generate these before before, you can do this with zip (inits xs) (tails xs).
Now the permutations of [1..n] will be
[] ++ 1 : [2..n] aka. [1..n], or
2 inserted (interleaved) somewhere into a permutation of [1], followed by [3..n]. But not 2 inserted at the end of [1], since we already go that result in the previous bullet point.
3 interleaved into a permutation of [1,2] (not at the end), followed by [4..n].
etc.
You can see that this is maximally lazy, since before we even consider doing something with 3, we have given all permutations that start with some permutation of [1,2]. The code that Yitzchak gave was
permutations xs = xs : concat (zipWith newPerms (init $ tail $ tails xs)
(init $ tail $ inits xs))
where
newPerms (t:ts) = map (++ts) . concatMap (interleave t) . permutations3
interleave t [y] = [[t, y]]
interleave t ys#(y:ys') = (t:ys) : map (y:) (interleave t ys')
Note the recursive call to permutations3, which can be a variant that doesn't have to be maximally lazy.
As you can see this is a bit less optimized than what we had before. But we can apply some of the same tricks.
The first step is to get rid of init and tail. Let's look at what zip (init $ tail $ tails xs) (init $ tail $ inits xs) actually is
*Main> let xs = [1..5] in zip (init $ tail $ tails xs) (init $ tail $ inits xs)
[([2,3,4,5],[1]),([3,4,5],[1,2]),([4,5],[1,2,3]),([5],[1,2,3,4])]
The init gets rid of the combination ([],[1..n]), while the tail gets rid of the combination ([1..n],[]). We don't want the former, because that would fail the pattern match in newPerms. The latter would fail interleave. Both are easy to fix: just add a case for newPerms [] and for interleave t [].
permutations xs = xs : concat (zipWith newPerms (tails xs) (inits xs))
where
newPerms [] is = []
newPerms (t:ts) is = map (++ts) (concatMap (interleave t) (permutations is))
interleave t [] = []
interleave t ys#(y:ys') = (t:ys) : map (y:) (interleave t ys')
Now we can try to inline tails and inits. Their definition is
tails xxs = xxs : case xxs of
[] -> []
(_:xs) -> tails xs
inits xxs = [] : case xxs of
[] -> []
(x:xs) -> map (x:) (inits xs)
The problem is that inits is not tail recursive. But since we are going to take a permutation of the inits anyway, we don't care about the order of the elements. So we can use an accumulating parameter,
inits' = inits'' []
where
inits'' is xxs = is : case xxs of
[] -> []
(x:xs) -> inits'' (x:is) xs
Now we make newPerms a function of xxs and this accumulating parameter, instead of tails xxs and inits xxs.
permutations xs = xs : concat (newPerms' xs [])
where
newPerms' xxs is =
newPerms xxs is :
case xxs of
[] -> []
(x:xs) -> newPerms' xs (x:is)
newPerms [] is = []
newPerms (t:ts) is = map (++ts) (concatMap (interleave t) (permutations3 is))
inlining newPerms into newPerms' then gives
permutations xs = xs : concat (newPerms' xs [])
where
newPerms' [] is = [] : []
newPerms' (t:ts) is =
map (++ts) (concatMap (interleave t) (permutations is)) :
newPerms' ts (t:is)
inlining and unfolding concat, and moving the final map (++ts) into interleave,
permutations xs = xs : newPerms' xs []
where
newPerms' [] is = []
newPerms' (t:ts) is =
concatMap interleave (permutations is) ++
newPerms' ts (t:is)
where
interleave [] = []
interleave (y:ys) = (t:y:ys++ts) : map (y:) (interleave ys)
Then finally, we can reapply the foldr trick to get rid of the (++):
permutations xs = xs : newPerms' xs []
where
newPerms' [] is = []
newPerms' (t:ts) is =
foldr (interleave id) (newPerms' ts (t:is)) (permutations is)
where
interleave f [] r = r
interleave f (y:ys) r = f (t:y:ys++ts) : interleave (f . (y:)) ys r
Wait, I said get rid of the (++). We got rid of one of them, but not the one in interleave.
For that, we can see that we are always concatenating some tail of yys to ts. So, we can unfold the calculating (ys++ts) along with the recursion of interleave, and have the function interleave' f ys r return the tuple (ys++ts, interleave f ys r). This gives
permutations xs = xs : newPerms' xs []
where
newPerms' [] is = []
newPerms' (t:ts) is =
foldr interleave (newPerms' ts (t:is)) (permutations is)
where
interleave ys r = let (_,zs) = interleave' id ys r in zs
interleave' f [] r = (ts,r)
interleave' f (y:ys) r =
let (us,zs) = interleave' (f . (y:)) ys r
in (y:us, f (t:y:us) : zs)
And there you have it, Data.List.permutations in all its maximally lazy optimized glory.
Great write-up by Twan! I (#Yitz) will just add a few references:
The original email thread where Twan developed this algorithm, linked above by Twan, is fascinating reading.
Knuth classifies all possible algorithms that satisfy these criteria in Vol. 4 Fasc. 2 Sec. 7.2.1.2.
Twan's permutations3 is essentially the same as Knuth's "Algorithm P". As far as Knuth knows, that algorithm was first published by English church bell ringers in the 1600's.
The basic algorithm is based on the idea of taking one item from the list at a time, finding every permutation of items including that new one, and then repeating.
To explain what this looks like, [1..] will mean a list from one up, where no values (no even the first) have been examined yet. It is the parameter to the function. The resulting list is something like:
[[1..]] ++
[[2,1,3..]] ++
[[3,2,1,4..], [2,3,1,4..]] ++ [[3,1,2,4..], [1,3,2,4..]]
[[4,3,2,1,5..], etc
The clustering above reflects the core idea of the algorithm... each row represents a new item taken from the input list, and added to the set of items that are being permuted. Furthermore, it is recursive... on each new row, it takes all the existing permutations, and places the item in each place it hasn't been yet (all the places other then the last one). So, on the third row, we have the two permutations [2,1] and [1,2], and then we take place 3 in both available slots, so [[3,2,1], [2,3,1]] and [[3,1,2], [1,3,2]] respectively, and then append whatever the unobserved part is.
Hopefully, this at least clarifies the algorithm a little. However, there are some optimizations and implementation details to explain.
(Side note: There are two central performance optimizations that are used: first, if you want to repeatedly prepend some items to multiple lists, map (x:y:z:) list is a lot faster then matching some conditional or pattern matching, because it has not branch, just a calculated jump. Second, and this one is used a lot, it is cheap (and handy) to build lists from the back to the front, by repeatedly prepending items; this is used in a few places.
The first thing the function does is establish a two bases cases: first, every list has one permutation at least: itself. This can be returned with no evaluation whatsoever. This could be thought of as the "take 0" case.
The outer loop is the part that looks like the following:
perms (t:ts) is = <prepend_stuff_to> (perms ts (t:is))
ts is the "untouched" part of the list, that we are not yet permuting and haven't even examined yet, and is initially the entire input sequence.
t is the new item we will be sticking in between the permutations.
is is the list of items that we will permute, and then place t in between, and is initially empty.
Each time we calculate one of the above rows, we reach the end of the items we have prepended to the thunk containing (perms ts (t:is)) and will recurse.
The second loop in is a foldr. It for each permutation of is (the stuff before the current item in the original list), it interleaves the item into that list, and prepends it to the thunk.
foldr interleave <thunk> (permutations is)
The third loop is one of the most complex. We know that it prepends each possible interspersing of our target item t in a permutation, followed by the unobserved tail onto the result sequence. It does this with a recursive call, where it folds the permutation into a stack of functions as it recurses, and then as it returns, it executes what amounts to a two little state machines to build the results.
Lets look at an example: interleave [<thunk>] [1,2,3] where t = 4 and is = [5..]
First, as interleave' is called recursively, it builds up ys and fs on the stack, like this:
y = 1, f = id
y = 2, f = (id . (1:))
y = 3, f = ((id . (1:)) . (2:))
(the functions are conceptually the same as ([]++), ([1]++), and ([1,2]++) respectively)
Then, as we go back up, we return and evalute a tuple containing two values, (us, zs).
us is the list to which we prepend the ys after our target t.
zs is the result accumulator, where each time we get a new permutation, we prepend it to the results lists.
Thus, to finish the example, f (t:y:us) gets evaluated and returned as a result for each level of the stack above.
([1,2]++) (4:3:[5..]) === [1,2,4,3,5..]
([1]++) (4:2[3,5..]) === [1,4,2,3,5..]
([]++) (4:1[2,3,5..]) === [4,1,2,3,5..]
Hopefully that helps, or at least supplements the material linked in the author's comment above.
(Thanks to dfeuer for bringing this up on IRC and discussing it for a few hours)

Remove 'take' from Haskell function

I'm new to Haskell, and am trying to work out how to stop my programs exploding when they hit the end of lists.
As an example, I have a function which mirrors a list of list of chars about the XY axis.
How can I rewrite this without the take?
mirrorXY' :: [[a]] -> [[a]]
mirrorXY' m = (map head m) : mirrorXY' (map tail m)
mirrorXY m = take (length $ m!!0) $ mirrorXY' m
P.S. I've just found transpose, but I'd still like an answer.
First, your mirrorXY' can be written with higher-order functions map and iterate instead of direct recursion:
mirr m = map (map head) . iterate (map tail) $ m
... and this blows up on hitting the empty list, as you've discovered:
*Main> map (map head) . iterate (map tail) $ [[1..4],[2..5],[3..6]]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[*** Exception: Prelude.head: empty list
Let's try it out without the first part:
*Main> iterate (map tail) $ [[1..4],[2..5],[3..6]]
[[[1,2,3,4],[2,3,4,5],[3,4,5,6]],[[2,3,4],[3,4,5],[4,5,6]],[[3,4],[4,5],[5,6]],[
[4],[5],[6]],[[],[],[]],[*** Exception: Prelude.tail: empty list
*Main>
So it's easy to fix: we just need to stop on hitting the [] in the input list:
*Main> takeWhile (not.null.head) . iterate (map tail) $ [[1..4],[2..5],[3..6]]
[[[1,2,3,4],[2,3,4,5],[3,4,5,6]],[[2,3,4],[3,4,5],[4,5,6]],[[3,4],[4,5],[5,6]],[
[4],[5],[6]]]
so, the function is
mirr xs = map (map head) . takeWhile (not.null.head) . iterate (map tail) $ xs
This presupposes that all the sublists are of equal lengths (or at least that the first one is the shortest), but that is easy to fix by tweaking the test in takeWhile:
mirr xs = map (map head) . takeWhile (all (not.null)) . iterate (map tail) $ xs
You need to handle the empty list, e.g.
mirrorXY [] = []
mirrorXY ([]:_) = []
mirrorXY m = (map head m) : mirrorXY (map tail m)
That assumes that the lists are of uniform length.
More robustly, something like
safeHead [] = Nothing
safeHead (a:_) = Just a
mirrorXY [] = []
mirrorXY m = case mapM safeHead m of
Nothing -> []
Just a -> a : mirrorXY (map tail m)
which stops on the first list that is too short. Note that this uses Maybes monad instance to do the short-circuiting via the mapM safeHead m line.
One could even write the last version more compactly, using maybe:
mirrorXY [] = []
mirrorXY m = maybe [] (: mirrorXY (map tail m)) $ mapM safeHead m
But this isn't necessarily clearer.