我试图让这个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
答案 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"