Composing monad actions with folds

后端 未结 3 711
醉梦人生
醉梦人生 2021-01-19 19:45

Let\'s take a function of type (Monad m) => a -> m a. For example:

ghci> let f x = Just (x+1)

I\'d like to be able to

相关标签:
3条回答
  • 2021-01-19 20:09

    I'd probably create some stricter variants of existing functions.

    {-# LANGUAGE BangPatterns #-}
    iterate' f !x = x : iterate' f (f x)
    ma >>=! f = do !a <- ma; f a
    times' n f a = iterate' (>>=! f) (return a) !! n
    

    Perhaps your problems stem from the fact that seq only evaluates the first argument to WHNF? If you're working on a complex structure, you may need a deeper seq, like deepseq.

    0 讨论(0)
  • 2021-01-19 20:34

    If you make f strict as in

    f x = let y = x+1 in y `seq` Just y
    

    or

    -- remember to enable -XBangPatterns
    f !x = Just (x+1)
    

    and leave the rest alone, your code runs in constant space (albeit slowly) even with very large n:

    ghci> times 4000000000 f 3
    Just 4000000003
    0 讨论(0)
  • 2021-01-19 20:34

    I came up with this:

     last $ take n $ iterate (>>= f) $ Just 1
    

    But it also overflows the stack on large numbers of n. I don't have the time right now to look into it more :-(

    0 讨论(0)
提交回复
热议问题