Operators.( .. .. ) throws an ArgumentException when ^Step does not implement IComparable
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
[`Operators.( .. .. )`](https://msdn.microsoft.com/visualfsharpdocs/conceptual/operators.%5B-..-..-%5D%5B%5Et,%5Estep%5D-function-%5Bfsharp%5D?f=255&MSPPError=-2147217396) throws an `ArgumentException` when `^Step` does not implement non-generic `System.IComparable`.
#### Repro steps
Run the following code:
```fsharp
type Step(value:int) =
member __.Value = value
static member Zero = Step 0
type Value(value:int) =
member __.Value = value
static member (+)(a:Value, b:Step) = Value(a.Value + b.Value)
interface System.IComparable with
member a.CompareTo(b) =
match b with
| :? Value as b' -> compare a.Value b'.Value
| _ -> failwith "unsupported"
[Value 0 .. Step 2 .. Value 2]
```
#### Expected behavior
I would expect a compiler error. Similar to
- `Step.Zero` not implemented
- `Value.(+)` not implemented
- `Value` not implementing `System.IComparable`
#### Actual behavior
The last line throws this exception:
```
System.ArgumentException: Failure during generic comparison: the type 'FSI_0006+Step' does not implement the System.IComparable interface. This error may be arise from the use of a function such as 'compare', 'max'
or 'min' or a data structure such as 'Set' or 'Map' whose keys contain instances of this type.
at Microsoft.FSharp.Core.LanguagePrimitives.HashCompare.FailGenericComparison[a](Object obj)
at Microsoft.FSharp.Core.LanguagePrimitives.HashCompare.GenericCompare(GenericComparer comp, Object xobj, Object yobj)
at Microsoft.FSharp.Core.LanguagePrimitives.HashCompare.GenericLessThanIntrinsic[T](T x, T y)
at Microsoft.FSharp.Core.Operators.OperatorIntrinsics.gen@4848-3[TStep,T](TStep zero, FSharpFunc`2 add, T start, TStep step, T stop, Unit unitVar0)
at Microsoft.FSharp.Core.Operators.OperatorIntrinsics.RangeStepGeneric@4936-1.System-Collections-Generic-IEnumerable`1-GetEnumerator()
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1.MoveNextImpl()
at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable`1 source)
at .$FSI_0006.main@()
```
#### Known workarounds
Run the code and realize you need to implement the interface `System.IComparable` on `Step`:
```fsharp
interface System.IComparable with
member a.CompareTo(b) =
match b with
| :? Step as b' -> compare a.Value b'.Value
| _ -> failwith "unsupported"
```
Or not using the `start .. step .. finish` operator, but generate the sequence somehow different (where `step` is not required to be comparable to `Zero` at runtime).
#### Related information
I had this issue when using 2 structs defined in C# and tried to iterate over them.
* Microsoft (R) F# Interactive version 10.2.3 for F# 4.5
* Microsoft Windows 10
Contributor guide
Assessment
This issue has not been assessed yet.