F# generics generic construct requires that the type 'struct (Guid * int)' have a public default constructor
Asked Answered
O

1

5

I have a interface in C# with method with this return type:

Task<(Guid, int)?>

I need to implement this interface in F# and if I am not mistaken this should be equivalent in F#:

Task<Nullable<ValueTuple<Guid, int>>>

Unfortunately when I compile I get this message:

generic construct requires that the type 'struct (Guid * int)' have a public default constructor

I have found some similar questions and looks like solution is usage of [<CLIMutable>] attribute. But that's not something what I can do with System.ValueTuple. Is there a way to use Nullable ValueTuple in F#?

Organize answered 19/6, 2018 at 17:52 Comment(0)
C
7

I think this is a compiler bug in F#. You might want to open an issue on the F# GitHub page and report this behavior. The reason I suspect it is a compiler bug is that I can make it work by simply unboxing struct (System.Guid, int) to ValueTuple<System.Guid, int>, which should already be equivalent types. Here's how I made it work in a sample, which may serve as a viable workaround for you as well, until someone more familiar with the F# compiler can let you know if it is a genuine bug or not:

open System
open System.Threading.Tasks

type ITest =
    abstract member F: unit -> Task<Nullable<ValueTuple<Guid, int>>>

type T () =
    interface ITest with
        member __.F () =
            let id = Guid.NewGuid()
            let x = Nullable(struct (id, 0) |> unbox<ValueTuple<Guid, int>>)
            Task.Run(fun () -> x)

(T() :> ITest).F().Result
Cadelle answered 19/6, 2018 at 18:9 Comment(1)
I have opened an issue on the F# GitHub for this behavior: github.com/Microsoft/visualfsharp/issues/5217Cadelle

© 2022 - 2024 — McMap. All rights reserved.