I can't really think straight today for whatever reason and I'm sure, there's an obvious simplification in here, but I came up with this:
import Control.Monad (replicateM)
things :: [String]
things = ["A","B","C","D"]
delimiters :: [String]
delimiters = ["and", ","]
result = map (++ " D") combinations''' where
combinations''' = map unwords combinations''
combinations'' = map concat combinations'
combinations' = map (map (\(x,y) -> [x,y])) combinations
combinations = map (zip $ init things) $ replicateM (length things - 1) delimiters
main = putStr $ unlines result
runhaskell program ~>
A and B and C and D
A and B and C , D
A and B , C and D
A and B , C , D
A , B and C and D
A , B and C , D
A , B , C and D
A , B , C , D
I'm too lazy to do commandline parsing, and the result of this doesn't fit exactly what you imagined, but it's fixable (tell me if you want me to make a standalone program).
The main logic is done by "map (zip $ init things) $ replicateM (length things - 1) delimiters".
"replicateM (length things - 1) delimiters" creates the (length things - 1)-fold Carthesian product of delimiters with itself, so e.g. when the delimiters are ["and", ","] and the number is 3 the result will be
[["and","and","and"],
["and","and",","],
["and",",","and"],
["and",",",","],
[",","and","and"],
[",","and",","],
[",",",","and"],
[",",",",","]]
These represent all combinations of delimiters between the "things". The rest of that line creates a new list consisting of lists of tuples, where each inner list has tuples like ("A","and"), ("B",","), etc representing all the permutations that things and delimiters go together, one inner list per possibility:
[[("A","and"),("B","and"),("C","and")],
[("A","and"),("B","and"),("C",",")],
[("A","and"),("B",","),("C","and")],
[("A","and"),("B",","),("C",",")],
[("A",","),("B","and"),("C","and")],
[("A",","),("B","and"),("C",",")],
[("A",","),("B",","),("C","and")],
[("A",","),("B",","),("C",",")]]
The rest of the computation of "result" just converts this into a nicer-to-look-at string.