1

I'm in my first few days of learning Haskell and I'm struggle with the Maybe type that is being returned from the Haskell's find function. I defined a function called FindNextState which takes in a tuple, and 2 Strings. This funcition calls getListOfNextStates which uses a lambda and pattern matching to get a list from the passed in tuple and then uses the find function's predicate I find a match in that list. The problem is find returns return a Maybe of my Transition type, this is preventing me from calling my getToState function because it's expecting at Transition. Is there anyway to convert the Maybe returned by find function?

Code

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 

Sample Input

findNextState dfa "s2" "0" Just ("s2","0","s3") *Main> :t findNextState dfa "s2" "0" findNextState dfa "s2" "0" :: Maybe Transisition 

** Desired Code**

findNextState :: DFA -> State -> Symbol -> State findNextState (_,_,_,tList) state symbol = getToState( (getListOfNextStates tList state symbol) ) 
7
  • 2
    What do you want it to do if it doesn't find a match? Commented Oct 9, 2018 at 23:22
  • I’d be fine with just returning a hardcode string value that says something like “failed” Commented Oct 9, 2018 at 23:23
  • 1
    Right now it returns Nothing if it doesn't find a match, which is a really good standard way of encoding a failure state. If you want findNextState to return Transition then you need to encode your failure state as a Transition somehow (you can't just return a string since that isn't a Transition). If you do that, the failure would be passed to getToState and processed, as if it was a successful find, which is probably not what you want. Leaving it as a Maybe is probably the preferred option, and you can use a case statement/pattern matching to extract the value. Commented Oct 9, 2018 at 23:34
  • Alternatively, if you're comfortable with the program just crashing with an error on a failed find, you can use fromJust :: Maybe a -> a. Not recommended in general, but it has its uses. Commented Oct 9, 2018 at 23:39
  • @DarthFennec I apologize, I'm very unfamiliar with this language. Are you saying I could create a function fromJust like this: fromJust :: Maybe Transisition-> Transisition fromJust a = a Commented Oct 9, 2018 at 23:46

1 Answer 1

6

I'd recommend keeping the Maybe, as it allows the code to fail gracefully if it doesn't find a match. If you do that, you'll leave getListOfNextStates returning Maybe Transition, and then change findNextState to return Maybe State. Now you can define it like this:

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 

Or more succinctly, you can use fmap :: (a -> b) -> Maybe a -> Maybe b (or its infix version, <$>) like so:

findNextState :: DFA -> State -> Symbol -> Maybe State findNextState (_,_,_,tList) state symbol = getToState <$> newstate where newstate = getListOfNextStates tList state symbol 

If you really don't think there will be a failed find, or you just don't care, you can use fromJust :: Maybe Transition -> Transition, like so:

import Data.Maybe getListOfNextStates :: [Transisition] -> State -> Symbol -> Transisition getListOfNextStates tList state symbol = fromJust (find (\(sState,sym,eState) -> matchTransition state symbol (sState,sym,eState)) tList) 

This will throw an exception if getListOfNextStates returns Nothing, effectively crashing the program. I wouldn't do this in real code unless you can absolutely ensure that it will never happen.

Sign up to request clarification or add additional context in comments.

1 Comment

Seeing this put the fromJust in prospective for me. For this particular use case I think I'm safe if the program crashes on bad input otherwise the fmap would definitively be the right way to go. Thank you so much for the help!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.