I don’t understand why the base case is needed in this:
-- perms :: Ord a => [a] -> [[a]]
perms [] = [[]]
perms xs = [ (x:ps) | x <- xs, ps <- perms (xs \\ [x])]
It seems to me that it should be automatic from the list-comprehension, but then I noticed that:
[ x:y | x<-[], y<-[] ]
evaluates to [], and not [[]], which seems surprising.
Even so, I was also surprised that without the base case it runs, but always gives [], which violates the type signature.
Is there an easy way to trace the execution of a list comprehension? It seems atomic to Debug.Trace.trace.
Let’s de-sugar!
Turns into
Now, more de-sugaring! Yay!
iirc,
>>=for lists isflip concatMap, andreturnis simply\x -> [x]Let’s only do a little bit of that replacement.
There, now do you see?
concatMap f []will obviously evaluate to[]. BecauseconcatMap fis justconcat . map f. So mapfonto the empty list, and then concatenate the results. Except there are no results, so the final evaluation is[].