生成任意长度haskell的真值表

时间:2014-12-01 13:52:52

标签: haskell combinations permutation

对于作业我必须生成如下的真值表:

combinations :: Int -> [[Bool]]

组合3应输出:

[[False, False, False],[False, False, True],[False, True, False],[False, True, True][True, False, False][True, False, True],[True, True, False],[True, True, True]]

我可以做一个列表理解:

combinations n = [[a,b] | a<-[True,  False], b <-[True, False]]

但这并不适用于任意数字。

你可以给我一个暗示吗?

2 个答案:

答案 0 :(得分:2)

你应该递归推理。

要生成n - 组合,您可以按以下步骤操作。首先,生成所有n-1 - 组合:将此列表命名为c(这是布尔列表的列表)。然后,对于xs的每个元素c(此处xs是布尔值列表),生成x:xs,其中x是任意布尔值。专门处理案例n=0,以提供基本案例。

答案 1 :(得分:1)

添加@chi的回答,这是实现该功能的递归方式。我已将其重命名为快捷方式truths

truths :: Int -> [[Bool]]
truths 0 = [[]]
truths n = do
    b <- [True,False]
    map (b :) (truths (n - 1))

最后3行可以改写为

truths n = [True,False] >>= \b -> map (b :) (truths (n - 1))

这里我们只是为前一个结果中的每个元素添加一个true / false值。唯一的边缘情况是负数,但你可以自己解决这个问题。

我在GHCi中尝试了这个解决方案,它在大约0.6秒内计算truths 10,这是令人印象深刻的,考虑到有1024个列表,每个列表包含10个元素。

我还使用sequence中的Control.Monad提出了另一个更有趣的版本:

import Control.Monad (sequence)

truths :: Int -> [[Bool]]
truths n = sequence (replicate n [True,False])

这将产生相同的输出。请注意,它也可以用无点样式重写,效果相同:

truths = sequence . flip replicate [True,False]