3

The fsi blocks when I try to combine these two transformers, without any warning or error message.

open FSharpPlus
open FSharpPlus.Data

type MyError = | Err of string

let f : WriterT<ResultT<Async<Result<_, MyError>>>> = monad {
    do! liftAsync <| Async.Sleep 30
    do! tell ["abc"]
    let! r0 = lift<| ResultT.hoist (Ok 25)
    return r0 + 5
    }

let g = monad {
    let! r1 = f
    do! tell ["def"]
    do! liftAsync <| Async.Sleep 50
    let! r2 = lift<| ResultT.hoist (Ok 2)
    return r1 + r2
    }

let runStackT stack = stack |> WriterT.run |> ResultT.run |> Async.RunSynchronously

#time "on"
let finalResult = runStackT g
#time "off"

What is the problem and how to make this code work?

Gus
  • 25,839
  • 2
  • 51
  • 76
Dwinky Doe
  • 31
  • 3
  • Interesting. Your code seems correct to me, even if it wasn't fsi shouldn't freeze, so this looks like an F# bug. I'll advice to open an issue in FSharpPlus to try to minimize it, eventually workaround it and report it to the F# compiler project. – Gus Dec 03 '19 at 20:44

1 Answers1

0

As stated in the comments, this is an F# bug.

Your code is correct, and even if it wasn't there's no reason why the F# compiler should hang.

I've found a workaround, if you change these lines:

...
let g: WriterT<ResultT<Async<Result<_, MyError>>>> = monad {
    let! r1 = f
    let! _ = tell ["def"]
    let! _ = liftAsync <| Async.Sleep 50
    let! r2 = WriterT.Lift <| ResultT.hoist (Ok 2)
    ...

it will work.

Note that changing a do! for a let! _ = is a trick I use frequently to improve type inference.

Gus
  • 25,839
  • 2
  • 51
  • 76
  • it still doesn't work. Always the same issue. Did you run the script? – Dwinky Doe Dec 07 '19 at 08:50
  • Yes, and it works. Though it takes a bit long to compile due to the 3 layered monads inference. I added a missing line in the fragment which stays as the original, I'm not sure if that was confusing you (probably not). After running the script you should get a warning about an F# generic instantiation, which doesn't prevent the code from compiling and running. – Gus Dec 07 '19 at 17:02