I know a bit of a Prolog and have just started some self-study in Haskell. I have been working through the 99 Problems for Haskell, learning much along the way and really enjoying Haskell. Sometimes I try to clarify my understanding of a problem space by coding something in Prolog and then thinking how that solution might relate to a functional approach in Haskell. Tonight, while working on the problems about logic (problems 47 and 48), I got distracted trying to accomplish the simple task of building up a list of the lists of all truth-value combinations with n values. I want a function tValues :: Int -> [[Bool]]
. This problem can be solved in a very straightforward and declarative way in Prolog, e.g.:
combinations_of_n_truth_values(N, AllValues) :-
findall(Values, n_truth_values(N, Values), AllValues).
n_truth_values(N, TruthValues) :-
length(TruthValues, N),
maplist(truth_value, TruthValues).
truth_value(true).
truth_value(false).
When used, the variable AllValues
will unify with the desired list of lists of truth-values. I would like to know how an experienced Haskell programmer would go about solving this same problem. I would expect there is an equally straightforward and declarative solution, but I can't seem to get my Haskell brain functioning in the right way.
I have fiddled with some semi-analogs using list comprehensions, such as the following:
tValues:: Int -> [[Bool]]
tValues 0 = []
tValues n = [v:vs | v <- tValue
, vs <- tValues (n-1) ]
tValue :: [Bool]
tValue = [True, False]
but tValues
only returns []
. I think I just need some human-to-human engagement to help shake my head clear and maybe grace me with a deeper insight.
Many thanks.