Skip to content

foldlM/foldrM doesn't work with Maybe and other pure monads #357

@matil019

Description

@matil019

The following code results in StackOverflowError:

import frege.data.Foldable (foldlM)

main = do
   let m :: Maybe Int
       m = foldlM (\r _ -> pure $! succ r) 0 [1..5000]
   println m
Exception in thread "main" java.lang.StackOverflowError
        at Main$$Lambda$17/930990596.<init>(Unknown Source)
        at Main$$Lambda$17/930990596.get$Lambda(Unknown Source)
        at Main.lambda$null$1(Main.java:85)
        at frege.prelude.PreludeBase.lambda$$$excl$18(PreludeBase.java:16226)
        at frege.run8.Thunk.call(Thunk.java:231)
        at Main.lambda$null$2(Main.java:95)
        at frege.run8.Thunk.call(Thunk.java:231)
        at frege.prelude.Maybe$IMonad_Maybe.ƒ$gt$gt$eq(Maybe.java:496)
        at frege.data.Foldable$1Let$10255.f$tick$8372(Foldable.java:1583)
        at frege.data.Foldable.lambda$foldlM$47(Foldable.java:1593)
        at frege.run8.Thunk.call(Thunk.java:231)
        at frege.prelude.Maybe$IMonad_Maybe.ƒ$gt$gt$eq(Maybe.java:497)
        at frege.data.Foldable$1Let$10255.f$tick$8372(Foldable.java:1583)
        at frege.data.Foldable.lambda$foldlM$47(Foldable.java:1593)
        at frege.run8.Thunk.call(Thunk.java:231)
        at frege.prelude.Maybe$IMonad_Maybe.ƒ$gt$gt$eq(Maybe.java:497)
        ...

foldrM has a similar problem. Either, [] cause StackOverflowError, too.

Meanwhile, IO doesn't suffer from this:

import frege.data.Foldable (foldlM)

main = do
    let m :: IO Int
        m = foldlM (\r a -> pure $! succ r) 0 [1..5000]
    println =<< m
5000

Workaround

UPDATE Having an undefined case changes the return type of Java method to Lazy, so the following seem to work for both finite and infinite lists (only for Maybe):

foldlM' :: (b -> a -> Maybe b) -> b -> [a] -> Maybe b
foldlM' f z (x:xs) = f z x >>= \acc -> foldlM' f acc xs
foldlM' _ z []     = pure z
foldlM' _ _ _      = undefined

main = do
    println $ foldlM' (\r _ -> Just $! succ r) 0 [1..100000]
    println $ foldlM' (\_ _ -> Nothing) 0 [1..]
Just 100000
Nothing

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions