我正处于学习Haskell的前几天,我正为从Haskell的Maybe
函数返回的find
类型而苦恼。我定义了一个名为FindNextState
的函数,它接收一个元组和2个字符串。此函数调用getListOfNextStates
,该函数使用lambda和模式匹配从传入的元组中获取列表,然后使用find
函数的谓词在该列表中找到匹配项。问题是查找返回返回我的Transition类型的Maybe
,这使我无法调用我的getToState
函数,因为它期望在Transition上进行。无论如何,是否可以转换由find函数返回的Maybe
?
代码
type State = String
type Symbol = String
type Transisition = (State, Symbol, State)
states = ["s0","s1"]
initState = "s0"
finalStates = ["s3"]
transisitionList = [("s0", "0", "s1"), ("s0", "1", "s1")]
dfa = (states, initState, finalStates, transisitionList)
getToState :: Transisition -> State
getToState (_, _, toState) = toState
findNextState :: DFA -> State -> Symbol -> Maybe Transisition --Maybe Transisition is the issue, I need it to be my type of Transisition otherwise Haskell throws an error when I load my program
findNextState (_,_,_,tList) state symbol = getListOfNextStates tList state symbol
getListOfNextStates :: [Transisition] -> State -> Symbol -> Maybe Transisition
getListOfNextStates tList state symbol = find(\(sState,sym,eState) -> matchTransition state symbol (sState,sym,eState)) tList
样本输入
findNextState dfa "s2" "0"
Just ("s2","0","s3")
*Main> :t findNextState dfa "s2" "0"
findNextState dfa "s2" "0" :: Maybe Transisition
**所需代码**
findNextState :: DFA -> State -> Symbol -> State
findNextState (_,_,_,tList) state symbol = getToState( (getListOfNextStates tList state symbol) )
答案 0 :(得分:7)
我建议保留Maybe
,因为如果找不到匹配项,它会使代码正常失败。如果这样做,您将使getListOfNextStates
返回Maybe Transition
,然后将findNextState
更改为返回Maybe State
。现在,您可以像这样定义它:
findNextState :: DFA -> State -> Symbol -> Maybe State
findNextState (_,_,_,tList) state symbol = case newstate of
Just s -> Just (getToState s)
Nothing -> Nothing
where newstate = getListOfNextStates tList state symbol
或更简洁地说,您可以像这样使用fmap :: (a -> b) -> Maybe a -> Maybe b
(或其中缀版本<$>
):
findNextState :: DFA -> State -> Symbol -> Maybe State
findNextState (_,_,_,tList) state symbol = getToState <$> newstate
where newstate = getListOfNextStates tList state symbol
如果您真的不认为查找失败,或者您根本不在乎,可以使用fromJust :: Maybe Transition -> Transition
,如下所示:
import Data.Maybe
getListOfNextStates :: [Transisition] -> State -> Symbol -> Transisition
getListOfNextStates tList state symbol = fromJust (find (\(sState,sym,eState) -> matchTransition state symbol (sState,sym,eState)) tList)
如果getListOfNextStates
返回Nothing
,这将引发异常,从而实际上导致程序崩溃。除非您可以绝对确保它永远不会发生,否则我不会在真实代码中这样做。