Search code examples
haskellbindingbindchain

How do I reuse an intermediate value in chain of Haskell Either binds?


I'm sure this has been answered but apparently I don't know what to search for.

I am working on my first non-trivial Haskell program -- a simulation of a card game I enjoy. I have the program working but there is a situation that I am certain can be handled better.

If I have a series of binds which are Either String TypeChangesBasedOnTheFunction.

playerInput <- getLine
case playerInput of
   {- CASE STUFF NOT IMPORTANT TO THIS QUESTION -}
   _ -> do let handValue = inputHasAllValidChars playerInput >>= makeDeckFromString >>= deckSubset (getCurrentPlayersDeck gameState) >>= whatHandRepresents >>= handBeatsCurrentTopTrick

Very soon after this part of the code runs, I need the value for whatHandRepresents. I can just run the same chain of binds again but I am certain there must be a better way by storing the value when it is determined in the code above.

My question is, is it possible to store this value. If so, how?


Solution

  • You have to thread it all the way back up to where you need it.

    repr <- case playerInput of
        -- now you have to return something of the appropriate type,
        -- say, `Left "didn't get it"`, from these other cases.
    
        _ -> do let repr = ... >>= whatHandRepresents
                    handValue = repr >>= handBeatsCurrentTopTrick
                -- use handValue
                return repr
    -- now use repr :: Either String HandRepresentationOrWhatever
    

    I sure hope you actually are using handValue within the default case and not trying to assign it for use later on. It will only be in scope within that case; if you want to use it afterward you have to return it also, just like repr (e.g. in a tuple).