2015-03-03 54 views
2

是否有一种算法可以引导给定数量的三值逻辑值的所有可能组合?三值逻辑值的所有可能组合

例如,F(2)应该返回这个列表:

t t 
t u 
t f 
u t 
u u 
u f 
f t 
f u 
f f 

功能看起来像这样(在Haskell):

data Tril = FALSE | NULL | TRUE 

all :: Int -> [[Tril]] 
all amount = ??? 

all1 :: [Tril] 
all1 = join (all 1) 

all2 :: [(Tril, Tril)] 
all2 = map (\[f, s] -> (f, s)) (all 2) 

all3 :: [(Tril, Tril, Tril)] 
all3 = map (\[f, s, t] -> (f, s, t)) (all 3) 

回答

7

你可以做到这一点很简单的列表理解:

all2 = [ (v1, v2) | v1 <- [FALSE, TRUE, NULL], v2 <- [FALSE, TRUE, NULL] ] 

可以等效写它作为一个单子做块:

all2 = do 
    v1 <- [FALSE, TRUE, NULL] 
    v2 <- [FALSE, TRUE, NULL] 
    return (v1, v2) 

这给了我们一个想法如何,我们事实证明—,这是

all 0 = [[]] -- Note: Empty list with one empty item. 
all n = do 
    v <- [FALSE, TRUE, NULL] 
    vs <- all (n-1) 
    return (v:vs) 

:可以写可变大小为一这是函数的净效果。它需要一个monadic动作,执行N次,并将结果汇​​总在一起。

all n = replicateM n [FALSE, TRUE, NULL] 
+0

感谢您的详细回答! – 2015-03-03 18:31:52

4

replicateM正是这么做的:

> import Control.Monad 
> replicateM 2 [1,2,3] 
[[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]] 

因此,

all :: Int -> [[Tril]] 
all amount = replicateM amount [FALSE,NULL,TRUE] 

我建议选择一个名字,因为all已被Prelude.all拍摄。

+0

感谢您的回答! :) – 2015-03-03 18:30:54