如何将foldM与字符串列表一起用作累加器?编程NFA

时间:2015-04-11 12:25:55

标签: list haskell monads fold

我试图让这个NFA工作,现在它很好地将一组(列表)状态转换到另一组状态。但是,当我尝试使用foldM时(我也会接受任何其他方法),我不能,因为foldM的类型是(Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b,我想要{{1}如果它可能是那样的话。主要问题在于函数(Foldable t, Monad m) => ([b] -> a -> m [b]) -> b -> t a -> m b

以下是代码:

testNFA

1 个答案:

答案 0 :(得分:4)

重写您的代码,以便transition具有State -> Symbol -> [State]类型。这就是NFA所拥有的:为了获得[State] -> Symbol -> [State]功能,你可以将这个调用联合起来。然后,您就可以轻松使用foldM

一个例子:

import Control.Monad

type Symbol = Char
type State  = String

data NFA = NFA { initialState :: State
               , isAccepting  :: State -> Bool
               , transition   :: State -> Symbol -> [State] }

-- https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton#Example
exampleNFA :: NFA
exampleNFA = NFA { initialState = "p"
                 , isAccepting  = (== "q")
                 , transition   = exampleTransition }

exampleTransition :: State -> Symbol -> [State]
exampleTransition "p" '0' = ["p"]
exampleTransition "p" '1' = ["p", "q"]
exampleTransition "q" '0' = []
exampleTransition "q" '1' = []

runNFA :: NFA -> String -> [State]
runNFA (NFA init _ trans) = foldM trans init

main = print $ runNFA exampleNFA "01101"