代码之家  ›  专栏  ›  技术社区  ›  VirtualProdigy

Haskell将Maybe转换为定义的类型

  •  0
  • VirtualProdigy  · 技术社区  · 6 年前

    Maybe find 功能。我定义了一个函数 FindNextState 包含一个元组和两个字符串。此函数调用 getListOfNextStates 它使用lambda和模式匹配从传入的元组中获取列表,然后使用 函数的谓词我在该列表中找到匹配项。问题是查找返回值 getToState 函数,因为它期望在转换时。有没有什么方法可以转换 也许 吧 由find函数返回?

    代码

    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) )
    
    1 回复  |  直到 6 年前
        1
  •  7
  •   DarthFennec    6 年前

    我建议你保持 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)
    

    退货 Nothing ,有效地破坏了程序。我不会在真正的代码中这样做,除非你能绝对确保它永远不会发生。