如何在状态机中的字符串上使用foldl / foldr?

时间:2019-05-17 20:56:30

标签: haskell functional-programming state-machine folding

我必须制造一个状态机,它等于文本编辑器的搜索功能。

我需要使用foldl / foldr将该功能应用于字符串的每个字符。

我有几个州必须与之合作:

type State = Int

start :: State
start = 0

accept :: State
accept = (-2)

reject :: State
reject = (-1)

我的类型是synonim:type Definition = [(State, Char -> State)]

该功能应如下所示:fsm :: Definition -> String -> Bool

我的代码现在看起来像这样:

transition :: Char -> State -> (Char -> State)

transition x y z
 | x == z = y
 | x == '*' = y
 | otherwise = reject

transitions :: [(Char, State)] -> (Char -> State)

transitions ((a,b):xs) e 
 | a == e || a == '*' = b
 | a /= e || a /= '*' = transitions xs e
 | otherwise = reject


step :: Definition -> State -> Char -> State

step ((a,b):xs) e f
 | a == e = b f
 | a /= e = step xs e f
 | otherwise = reject

它具有开始状态,应用过渡或过渡功能,如果被接受,则接受的状态是下一个开始状态。

这里有一些测试用例,我必须测试一下功能:

fsm [ (start, transition '*' accept)] "x" == True

fsm [ (start, transition 'a' 1)
    , (1, transition 'l' 2)
    , (2, transition '*' accept)
    ] "alma" == True

fsm [ (start, transition '*' 1)
    , (1, transition '*' 2)
    , (2, transition 'x' 3)
    , (3, transition '*' accept)
    ] "taxi" == True

fsm [ (start, transitions [('\n',accept), ('*', 1)])
    , (1, transition '*' start) 
    ] "aa\n" == True

1 个答案:

答案 0 :(得分:0)

如果您填写初始状态并在foldl中处理字符串,则这些类型基本上意味着其余:

-- foldl :: Foldable t => (State -> Char -> State) -> State -> [Char] -> State
fsm def str = foldl x start str

这里x的类型必须为State -> Char -> State,并在给定当前字符和下一个字符的情况下为您提供下一个状态,这就是给定step的{​​{1}}函数所做的你有。这给您:

Definition

现在您有一个fsm def str = foldl (step def) start str :: State ,但需要一个State来说明是否被接受,这只是一个简单的比较:

Bool