2015-03-03 51 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