timothyylim
timothyylim

Reputation: 1527

Handle maybe in do block and extract a value

I'm reading a yaml which results in a maybe:

main :: IO ()
main = 
  do 
     justConfig <- decodeFile "config.yaml" :: IO (Maybe Config)
     case justConfig of
       Just config -> initState $ config
       Nothing -> initState $ (Map.fromList [("hi", "bye")]) 

How would you extract the result of initState from:

do      
  Just config ... 
  state <- initState $ config 

Upvotes: 1

Views: 96

Answers (1)

chepner
chepner

Reputation: 531948

You can use a nested do block which uses a different monad, but you need to ensure it is used where the resulting monadic type is expected. For example, suppose you have a function foo :: StateMonad Foo -> IO (). Then you can write the following, assuming initState :: Config -> StateMonad State.

main = do -- IO monad
   let defaultConfig = Map.fromList [("hi", "bye")]
   config <- fromMaybe defaultConfig <$> decodeFile "config.yaml"
   foo $ do -- StateMonad monad
     state <- initState config  -- initState config :: StateMonad State
                                -- state :: State
     ...
     return x  -- x :: Foo

Upvotes: 4

Related Questions