When to use Haskell monads

前端 未结 2 904
情话喂你
情话喂你 2021-01-31 05:13

I\'m implementing a combinatorial optimization algorithm in Haskell:

Given an initial candidate solution, repeat until stopping criteria are met:

  1. Determine         


        
2条回答
  •  无人及你
    2021-01-31 05:48

    Here's a pseudocodey sketch of how you might use the State monad to thread the search state through the computation:

    import Control.Monad.State
    
    type SearchState = ...
    type Move = ...
    type Fitness = ...
    
    determineMoves :: State SearchState [Move]
    determineMoves = do
      -- since determineMoves is in the State monad, we can grab the state here
      st <- get
      ...
    
    evaluateMoves :: [Move] -> [(Move, Fitness)]
    evaluateMoves = ...
    
    chooseMove :: [(Move, Fitness)] -> Move
    chooseMove = ...
    
    -- makeMove is not itself monadic, but operates on the SearchState
    -- type we're threading through with the State monad
    makeMove :: Move -> SearchState -> SearchState
    makeMove m st = ...
    
    loop :: State SearchState ()
    loop = do
      moves <- determineMoves
      let candidates = evaluateMoves moves
          move = chooseMove candidates
      -- we pass a function (SearchState -> SearchState) to modify in 
      -- order to update the threaded SearchState
      modify (makeMove move)
      loop
    

    Notice that even though your main computation is in the state monad, not every component has to be in the monad. Here, evaluateMoves and chooseMove are non-monadic, and I've used let to show you how to explicitly integrate them into a do block. Once you get comfortable with this style, though, you'll probably want to get comfortable using <$> (aka fmap) and function composition to get more succinct:

    loop :: State SearchState ()
    loop = do
      move <- (chooseMove . evaluateMoves) <$> determineMoves
      modify (makeMove move)
      loop
    

提交回复
热议问题