You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was playing a bit with the new feature that allows implicit yields and realized that it's a good thing to write custom collections, like semigroups as the CE can't be empty.
But soon realized that it requires a Zero method, even when it is not used at all.
Repro steps
type NonEmpty<'t> = list<'t> // for simplicity
type NelBuilder () =
member __.Zero () = invalidOp "A NonEmptyList doesn't support the Zero operation."
member __.Combine (a: NonEmpty<'T>, b) = a @ b
member __.Yield x = List.singleton x
member __.Delay expr = expr () : NonEmpty<'T>
let nel = NelBuilder ()
let x = nel {1; 2; 3}
// val x : NonEmpty<int> = [1; 2; 3]
type NelBuilder2 () =
// member __.Zero () = invalidOp "A NonEmptyList doesn't support the Zero operation."
member __.Combine (a: NonEmpty<'T>, b) = a @ b
member __.Yield x = List.singleton x
member __.Delay expr = expr () : NonEmpty<'T>
let nel2 = NelBuilder2 ()
let y = nel2 {1; 2; 3}
// ~vsA01F.fsx(22,21): error FS0708: This control construct may only be used if the computation expression builder defines a 'Zero' method
type NelBuilder3 () =
// member __.Zero () = invalidOp "A NonEmptyList doesn't support the Zero operation."
member __.Combine (a: NonEmpty<'T>, b) = a @ b
member __.Yield x = List.singleton x
member __.Delay expr = expr () : NonEmpty<'T>
let nel3 = NelBuilder3 ()
let y = nel3 {1; 2; 3; ()}
// ~vsA01F.fsx(33,24): error FS0708: This control construct may only be used if the computation expression builder defines a 'Zero' method
Expected behavior
Sample with nel compiles although Zero is not called.
Sample with nel2 compiles as Zero is not called.
Sample with nel3 doesn't compile as Zero is called.
Actual behavior
Sample with nel compiles although Zero is not called.
Sample with nel2doesn't compile even though Zero is never called.
Sample with nel3 doesn't compile as Zero is called.
Known workarounds
Define a Zero method that throws a runtime exception but it defeats a bit the purpose of a compile-time non-empty-collection, as sample 1 would start compiling but failing at runtime.
I was playing a bit with the new feature that allows implicit yields and realized that it's a good thing to write custom collections, like semigroups as the CE can't be empty.
But soon realized that it requires a
Zero
method, even when it is not used at all.Repro steps
Expected behavior
Sample with
nel
compiles although Zero is not called.Sample with
nel2
compiles as Zero is not called.Sample with
nel3
doesn't compile as Zero is called.Actual behavior
Sample with
nel
compiles although Zero is not called.Sample with
nel2
doesn't compile even though Zero is never called.Sample with
nel3
doesn't compile as Zero is called.Known workarounds
Define a Zero method that throws a runtime exception but it defeats a bit the purpose of a compile-time non-empty-collection, as sample 1 would start compiling but failing at runtime.
Related information
Original comment: fsharp/fslang-suggestions#643 (comment)
The text was updated successfully, but these errors were encountered: