How would one do the following in Haskell:
Return all permutations of a list where one element comes before the another element (cannot assume that elements of the list can be ordered)?
My solution was to do:
sLeftOf l r lss = [ ls | ls <- lss , DL.findIndex (l==) ls <= DL.findIndex (r==) ls ]
for somewhere to the left of and
sDirectLeftOf l r lss = [ls | ls <- lss , DL.findIndex (l==) ls == fmap (\x-> x - 1) (DL.findIndex (r==) ls) ]
for directly to the left of which works,
*Main Lib> sLeftOf 2 3 (permutations [1..3]) [[1,2,3],[2,1,3],[2,3,1]] *Main Lib> sDirectLeftOf 2 3 (permutations [1..4]) [[1,2,3,4],[2,3,1,4],[4,2,3,1],[2,3,4,1],[4,1,2,3],[1,4,2,3]]
But I don't like these. The
findIndex seems un-Haskelly and the
fmap on the result of
findIndex feels just wrong. Anyone has better ways to do this? For two lists there is a nice method using
mylist = do x <- permutations ["a","b","c"] y <- permutations ["1","2","3"] leftOf "b" x "3" y return $ zip x y where leftOf x xs y ys = guard $ (x,y) `elem` zip xs (tail ys) leftOf' x xs y ys = guard $ (x,y) `elem` (aux xs (tail ys)) aux a b@(_:ys) = (zip a b) ++ aux a ys aux _  =  reqA = (map (map fst )) mylist reqB = (map (map snd )) mylist required = zip reqA reqB
leftOf is immediately to left of and the second is somewhere to the left of; but this won't work for a single list.