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

Haskell 如何在状态机中的字符串上使用foldl/foldr?,haskell,functional-programming,state-machine,folding,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::Definitio

我必须做一个状态机,它相当于一个文本编辑器的搜索功能

我需要使用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

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

-- foldl :: Foldable t => (State -> Char -> State) -> State -> [Char] -> State
fsm def str = foldl x start str
在这里,x必须输入State->Char->State,并根据当前状态和下一个字符为您提供下一个状态,这就是给定定义的step函数所做的。这将为您提供:

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

fsm def str = foldl (step def) start str == accept

您的问题是什么?如何使用foldl或foldrIt编写fsm函数是您尝试实现此目标的责任。如果您发现您的方法不起作用,即使在非常努力地尝试之后也无法找出原因,那么请概述您采取的方法,您期望该方法的结果是什么,为什么,以及实际结果是什么。如果实际结果是编译器错误,那么正确的沟通方式是将完整的错误复制并粘贴到问题中。然后,我们可以帮助您识别推理中的缺陷。