Simulating interacting stateful objects in Haskell

前端 未结 3 1527
故里飘歌
故里飘歌 2020-12-20 12:27

I\'m currently writing a Haskell program that involves simulating an abstract machine, which has internal state, takes input and gives output. I know how to implement this u

3条回答
  •  攒了一身酷
    2020-12-20 12:55

    One option is to make your state transformations into pure functions operating on Machine values:

    getValue :: Machine -> Int
    getValue (Register x) = x
    
    addToState :: Int -> Machine -> Machine
    addToState i (Register x) = Register (x + i)
    

    Then you can lift them into State as needed, writing State actions on multiple machines like so:

    doInteraction :: State (Machine, Machine) Int
    doInteraction = do
      a <- gets $ getValue . fst
      modify $ first $ addToState (-a)
      modify $ second $ addToState a
      gets $ getValue . snd
    

    Where first (resp. second) is a function from Control.Arrow, used here with the type:

    (a -> b) -> (a, c) -> (b, c)
    

    That is, it modifies the first element of a tuple.

    Then runState doInteraction (Register 3, Register 5) produces (8, (Register 0, Register 8)) as expected.

    (In general I think you could do this sort of “zooming in” on subvalues with lenses, but I’m not really familiar enough to offer an example.)

提交回复
热议问题