question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

>=1.3.0 breaks type inference of unwrapped types

See original GitHub issue

Thanks again for fixing #86. After updating to 1.4.1, however, I still get errors from code which compiled with 1.2.6.

Here’s a minimal repro:

type X() = 
   member _.A = 1

let f () = asyncResult {
    let! v = async { return X() }
    return v.A
}

Under 1.2.6, this compiles. Under 1.4.1, the compiler can’t figure out the type of v' and errors out with a “lookup of indeterminate object type” on v'.A

Note that if you replace X() with a record, the code may compile because F# will infer types from members of records, but not from members of classes and anonymous records.

Possible workaround: unwrap v inside a regular async CE instead:

let f () = asyncResult {
    let v = async { return X() }
    return! async { let! v' = v in return v'.A }
}    

I’ll still need to roll back to 1.2.6 though because we have this pattern every single time we make a database query:

asyncResult {
    use cmd = Db.Query(connStr)
    let! records = cmd.AsyncExecute(args)
    // do stuff with records
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:17

github_iconTop GitHub Comments

1reaction
piastecommented, Jul 2, 2020

I too vote 2. As I mentioned, we use this type inference every single time we make a database query, and we cannot add a type annotation because the type is generated by the type provider and doesn’t have a usable name.

On the other side, the issue #86 (that the Bind in #87 resolved) only appears in a couple of spots through our codebase, and a workaround should be possible, since all CEs are just sugar, although it seems a bit tricky.

For reference, take this piece of v1.2.6 code:

    let f () = asyncResult { return ""  }

    let g () = 

        asyncResult {        
            let! r1 = f ()   
            let! (r2 : Result<string, _>)  = f ()
            return (r2 = Ok r1)        
        }

Not sure how this could be done in v1.4.0 without forsaking the use of asyncResult entirely.

0reactions
piastecommented, Jul 3, 2020

@TheAngryByrd the issue happened when we had a long taskResult computation, as usually every API endpoint is a single taskResult CE, but at one particular point in the flow we had an error return that we were able to handle on the spot instead of returning a HTTP failure. Restructuring the entire CE to be a plain async with manual error handling would not be worth it.

For now, I’ve solved it somewhat clumsily by running the right side of the unwrapping throgh Task.map (function | Ok x -> Choice1Of2 x | Error y -> Choice2Of2 y), so the Choice doesn’t get unwrapped and it can be handled manually.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Force binding on top wrapper · Issue #86
Just found this broke some of our code after running a test paket update . ... >=1.3.0 breaks type inference of unwrapped types...
Read more >
Implicitly Unwrapped Optionals in Swift
An implicitly unwrapped optional is similar to a regular optional, but is automatically unwrapped when accessed. This means that you can access the...
Read more >
typescript: generic constraints cause type inference to pick ...
I'm trying to constrain the Set builder to accept only types for which equality is properly defined (to avoid this problem). strange.d.ts
Read more >
Type Checking and Inference for Dynamic Languages
Type inference is a generalization of type checking that automatically infers types while performing checking. However, stan- dard type inference often ...
Read more >
CHANGELOG.md
Breaking Change #50383: Report a compile-time error for all cyclic dependencies during top-level type inference. Previously, some of these dependencies were ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found