
Daniel,
Instead of
if checkStreet s then ... else [], use Control.Monad.guard:
test = do ds <- drinkPerms ns <- nationPerms let s = Street $ makeHouses ds ns [] [] [] guard (checkStreet s) ss <- smokePerms ...
Excellent. That really cleans it up!
I'm also open to any comments about making better use of the different Haskell idioms.
There is a function permutations in Data.List, you can use that instead of writing your own (except if you want the permutations in a different order). xxxPerms = permutationsOf [toEnum 0 .. toEnum 4] :: [[XXX]] isn't particularly nice, better give the first and last constructor of each type or define allPerms :: (Enum a, Bounded a) => [[a]] allPerms = permutationsOf [minBound .. maxBound] and derive also Bounded for your types.
Great! I tried to do something a bit like that using typeclasses, but I got lost along the way.. :( I love how allPerms generates the correct permutations using type inference!
nationPerms = filter rule1 $ permutationsOf [toEnum 0 .. toEnum 4] :: [[Nation]] where rule1 ns = (ns !! 0) == Norway
is very inefficient, make that nationPerms = map (Norway:) $ permutationsOf [England .. Denmark] (yes, it's not so terrible for only five items, still it made me wince). Similar for drinkPerms.
How do you do it with drinkPerms? The constant element is in the middle (with Nations it seems easier since it's the first one).
checkCond (f,c) h = fmap (== c) (f h) ~> checkCond (f,c) = fmap (== c) . f
Ok. Hopefully someday these patterns will be obvious... Thanks a lot, Patrick -- ===================== Patrick LeBoutillier Rosemère, Québec, Canada