Comment detail

与えた条件を満たす候補 (Nested Flatten)
こんな感じ。
*Main> f ["and","or","not","and"]
(True,True,True,True)
(True,True,False,True)
(True,False,False,True)
(False,True,False,True)
(False,False,False,True)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
t :: (Bool -> Bool) -> [Bool] -> [String] -> Bool
t prev (x:[]) _ = prev x
t prev (x:xs) (op:ops) | op == "not" = t prev (not x:xs) ops
                       | op == "and" = t ((&&) (prev x)) xs ops
                       | op == "or"  = t ((||) (prev x)) xs ops

f :: [String] -> IO ()
f ops = mapM_ print [(b1,b2,b3,b4) | bs@(b1:b2:b3:[b4]) <- bss, test bs ops]
  where bss = sequence $ replicate 4 [True,False]
        test = t id
guard をつかってみた
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Control.Monad

starling f g x = f x (g x)

f :: [String] -> [[Bool]]
f cs = sequence (replicate 4 [False,True])
   >>= starling ((>>) . guard . flip (t id) cs) return

t :: (Bool -> Bool) -> [Bool] -> [String] -> Bool
t prev [x]    _           = prev x
t prev (x:xs) ("not":ops) = t prev (not x:xs) ops
t prev (x:xs) ("and":ops) = t (prev x &&) xs  ops
t prev (x:xs) ("or" :ops) = t (prev x ||) xs  ops

{-
*Main> f ["and","or","not","and"]
[[False,False,False,True]
,[False,True,False,True]
,[True,False,False,True]
,[True,True,False,True]
,[True,True,True,True]]
-}
関数型っぽいですね。
foldl を使って写経。(test の部分のみ)
1
2
3
4
5
6
test xs ops = p x where
  (p, x:_) = foldl f (id, xs) ops
  f (prev, x:xs) op
    | op == "not" = (prev, not x:xs)
    | op == "and" = (((&&) (prev x)), xs)
    | op == "or" = (((||) (prev x)), xs)

Index

Feed

Other

Link

Pathtraq

loading...