You need sequence :: Monad m => [ma] -> m [a] .
In particular, for the monad [] sequence takes a list of lists n and returns all lists of length n that draw one element from each list.
sequence [ [1,2,3], [4,5], [6] ] = [ [1,4,6], [1,5,6], [2,4,6], [2,5,6], [3,4,6], [3,5,6] ]
This helps in your specific case, because if you have a list of n lines, you can easily create features for each line:
map (\s -> [(s,True), (s,False)] ["a", "b", "c"] = [ [("a", True), ("a", False) ] , [("b", True), ("b", False) ] , [("c", True), ("c", False) ] ]
now you just need to select one from each list to get your sentences containing the truth value for each variable:
sequence (map (\s -> [(s,True), (s,False)] ["a", "b", "c"]) = [ [("a", True), ("b", True), ("c", True)] , [("a", True), ("b", True), ("c", False)] , [("a", True), ("b", False), ("c", True)] , [("a", True), ("b", False), ("c", False)] , [("a", False), ("b", True), ("c", True)] , [("a", False), ("b", True), ("c", False)] , [("a", False), ("b", False), ("c", True)] , [("a", False), ("b", False), ("c", False)] ]
sequence (map f xs) appears often enough to have a name there:
mapM f xs = sequence (map f xs) -- or, point-free style mapM f = sequence . map f
So your desired function is just
allPropositions vs = mapM (\v -> [(v,True),(v,False)]) vs -- or, equivalently allPropositions = mapM (\v -> [(v,True),(v,False)]) -- or, equivalently allPropositions = mapM $ \v -> [(v,True),(v,False)] -- or, equivalently, with -XTupleSections allPropositions = mapM $ \v -> map (v,) [True, False]