amb :: [a] -> [a] amb xs = xs require :: Bool -> [()] require True = [()] require False = [] distinct :: (Eq a) => [a] -> Bool distinct [] = True distinct (x:xs) = (and $ map (/=x)xs) && distinct xs dwellings = do baker <- amb [1..5] cooper <- amb [1..5] fletcher <- amb [1..5] miller <- amb [1..5] smith <- amb [1..5] require $ distinct [baker, cooper, fletcher, miller, smith] require $ baker /= 5 require $ cooper /= 1 require $ fletcher /= 5 require $ fletcher /= 1 require $ miller > cooper require $ (abs $ smith - fletcher) /= 1 require $ (abs $ cooper - fletcher) /= 1 return $ [("baker", baker), ("cooper", cooper), ("fletcher", fletcher), ("miller", miller), ("smith", smith)] main :: IO () main = putStrLn $ show dwellings