这是我尝试在Haskell中执行DFA。 DFA工作,但现在我希望它读取一些文件而不是硬编码表。是使用foldl
完成的。现在的问题是我需要定义函数table
,我希望函数t
不需要定义table
,只需从内存中获取它。如果我在t
中使用3个参数,那么我就无法使用foldl
。
module DFA where
data DFA = DFA { intialState :: String
, isAccepting :: String -> Bool
, transition :: String -> Char -> String
}
-- estado inicial
i = "Q1"
-- criterio de aceptación
a = (`elem` ["Q1"])
table :: [((String, Char), String)]
table = [(("Q1",'A'), "Q2")
,(("Q1",'B'), "Q1")
,(("Q2",'A'), "Q1")
,(("Q2",'B'), "Q2")]
strToRow :: [String] -> [((String, Char), String)]
strToRow str = map crea_tupla por_espacios
where
crea_tupla [x,y,z] = ((x, head y), z)
por_espacios = map words str
readDFA :: String -> IO ()
readDFA filename = do
contenidos <- readFile filename
print . strToRow . lines $ contenidos
t n c = case lookup (n,c) table of
Just x -> x
_ -> error "transición errónea"
dfa = DFA i a t
testDFA :: DFA -> [Char] -> Bool
testDFA (DFA i a t) = a . foldl t i
文件格式很简单,只有状态字符下一个:
Q1 A Q2
Q1 B Q1
Q2 A Q1
Q2 B Q2
答案 0 :(得分:2)
即使添加第三个参数,也可以使用foldl
。假设你定义了
t tab n c = case lookup (n,c) tab of
Just x -> x
_ -> error "transición errónea"
以便t
对新参数tab
起作用,而不是固定table
。要使用foldl
,您现在需要使用
dfa = DFA i a (t table)
这是因为t tab
是一个双参数函数,通过修复它的第一个参数从三个参数函数t
获得。为了实现这一点,table
必须是您刚刚从文件中读取的内容。也许你需要像(完全未经测试的):
readDFA :: String -> IO ()
readDFA filename = do
contenidos <- readFile filename
let table = strToRow . lines $ contenidos
dfa = DFA i a (t table)
print (testDFA dfa "some string")