Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SingleOrDefault() throws a NullReferenceException in F# [duplicate]

Tags:

f#

The code below throws a NullReferenceException within the FirstOrDefault() method:

open System
open System.Collections.Generic
open System.Linq

[<EntryPoint>]
let main argv = 
    let suspects = seq {
        yield ("Frank", 1.0)
        yield ("Suzie", 0.9)
        yield ("John", 0.5)
        // yield ("Keyser Soze", 0.3)
    }
    let likely = suspects.FirstOrDefault(fun (name, confidence) -> name = "Keyser Soze")
    printfn "Name: %s" (fst likely)
    Console.ReadLine() |> ignore
    0

What's the best way to work around that? Catching it seems wrong. I could grab the iterator manually and put it in a while loop, but that's - well, wrong on so many levels.

[Edit] I can't even do what I would do in C#, namely, check to see if the result is null or default, for two reasons: (1) The error is thrown in the FirstOrDefault() method, not when I reference the result; and (2) if I try to check for null, the compiler complains that `The type '(string * float)' does not have 'null' as a proper value':

    if likely = null then            
        printfn "Nothing to see here"

Any suggestions?

like image 242
Ken Smith Avatar asked Aug 14 '26 07:08

Ken Smith


1 Answers

As noted above, Seq.tryFind is the idiomatic way of achieving that. If you really must use FirstOrDefault() you could do something like this:

open System.Collections.Generic
open System.Linq
let suspects = seq {
    yield Some("Frank", 1.0)
    yield Some("Suzie", 0.9)
    yield Some("John", 0.5)
    // yield ("Keyser Soze", 0.3)
}
let likely = suspects.FirstOrDefault(fun x -> let name, confidence = x.Value
                                              name = "Keyser Soze")
match likely with
| Some(x) -> printfn "Name: %s" (fst x)
| None -> printfn "Not Found"
like image 54
N_A Avatar answered Aug 17 '26 12:08

N_A



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!