Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic stateful loop in Haskell

Tags:

haskell

Is there an idiomatic way to express following code in Haskell?

main :: IO ()
main = loop initState1 initState2 initState3

loop :: State1 -> State2 -> State3 -> IO ()
loop s1 s2 s3 = do
  s1' <- runService1 s1
  s2' <- runService2 s2
  s3' <- runService3 s3
  loop s1' s2' s3'

This code is very verbose so I probably doing something weird.

like image 368
user1518183 Avatar asked Jul 26 '18 00:07

user1518183


1 Answers

main = fix (zipWithM ($) >=>)
  [runService1, runService2, runService3]
  [initState1 , initState2 , initState3 ]

Compare fix . (>>=) :: IO a -> IO b, which is forever.

Edit: This only works if State1 = State2 = State3. If not, data-fix allows:

main = fix (traverse unFix >=>)
  [ana runService1 initState1, ana runService2 initState2, ana runService3 initState3]
like image 143
Gurkenglas Avatar answered Oct 20 '22 13:10

Gurkenglas