Open En3Tho opened 5 months ago
Note: Works fine when chaining op_Addition
calls.
For reference — these tests should be extended to cover this:
Note: Works fine when chaining
op_Addition
calls.
Yes, as in
let numericOpsPlus<'T when INumber<'T>> (num: 'T) =
num
|> fun num' -> 'T.(+) (num, num')
|> fun num' -> 'T.(+) (num, num')
or
let numericOpsPlus<'T when INumber<'T>> (num: 'T) =
num
|> fun num' -> 'T.op_Addition (num, num')
|> fun num' -> 'T.op_Addition (num, num')
or
let numericOpsPlus<'T when INumber<'T>> (num: 'T) =
let (+) x y = 'T.(+) (x, y)
num + num + num
Note: Works fine when chaining
op_Addition
calls.Yes, as in
let numericOpsPlus<'T when INumber<'T>> (num: 'T) = num |> fun num' -> 'T.(+) (num, num') |> fun num' -> 'T.(+) (num, num')
or
let numericOpsPlus<'T when INumber<'T>> (num: 'T) = num |> fun num' -> 'T.op_Addition (num, num') |> fun num' -> 'T.op_Addition (num, num')
or
let numericOpsPlus<'T when INumber<'T>> (num: 'T) = let (+) x y = 'T.(+) (x, y) num + num + num
Yes, also:
open System.Numerics
let numericOpsPlusPlus<'T when INumber<'T>>(num: 'T) =
((num + num) : 'T) + num
and
open System.Numerics
let numericOpsPlusPlus<'T when INumber<'T>>(num: 'T) =
'T.op_Addition('T.op_Addition(num, num), num)
We suffer flexibility of the (+)
here. I am not fully sure we can "fix" it here without seriously breaking something. I wonder if it's the same with some other operators (maybe not that common in F#).
Yes, also:
open System.Numerics let numericOpsPlusPlus<'T when INumber<'T>>(num: 'T) = ((num + num) : 'T) + num
This might show where the problem is: something is probably getting confused when looking at the multiple type parameters in IAdditionOperators<'TSelf, 'TOther, 'TResult>
and trying to unify the 'TResult
of the first application with the 'TOther
of the second.
Yes, also:
open System.Numerics let numericOpsPlusPlus<'T when INumber<'T>>(num: 'T) = ((num + num) : 'T) + num
This might show where the problem is: something is probably getting confused when looking at the multiple type parameters in
IAdditionOperators<'TSelf, 'TOther, 'TResult>
and trying to unify the'TResult
of the first application with the'TOther
of the second.
It's probably only in conjunction with + (might be others too).
IAdditionOperators<'TSelf, 'TOther, 'TResult> and trying to unify the 'TResult of the first application with the 'TOther of the second.
@brianrourkeboll regarding the above, since it's constrained via INumber, I would expect it to have all typars to be unified.
It's probably only in conjunction with + (might be others too).
It does for the other System.Numerics
operators (-
, *
, %
, unary +
and -
, etc.).
Interestingly, this does not trigger the problem:
open System.Numerics
#nowarn "3535"
type IFace<'a, 'b, 'c> =
static abstract (>*..*<) : 'a * 'b -> 'c
let customOps<'T when IFace<'T, 'T, 'T>> (num: 'T) =
num >*..*< num >*..*< num
type T =
| T of int
interface IFace<T, T, T> with
static member (>*..*<) (T a, T b) = T (a + b)
customOps (T 1)
It's probably only in conjunction with + (might be others too).
It does for the other
System.Numerics
operators (-
,*
,%
, unary+
and-
, etc.).Interestingly, this does not trigger the problem:
open System.Numerics #nowarn "3535" type IFace<'a, 'b, 'c> = static abstract (>*..*<) : 'a * 'b -> 'c let customOps<'T when IFace<'T, 'T, 'T>> (num: 'T) = num >*..*< num >*..*< num type T = | T of int interface IFace<T, T, T> with static member (>*..*<) (T a, T b) = T (a + b) customOps (T 1)
Yeah, many of the "standard" operators have somewhat special treatment.
By the way, this is how I found this bug: https://github.com/m4rs-mt/ILGPU/issues/463#issuecomment-2061598101
I've been playing with F# and ILGpu and so far it feels quite nice.
When using inline, code does compile to
public static T numericOpsPlus<T>(T num) where T : INumber<T>
{
T val = num + num;
return val + num;
}
Please provide a succinct description of the issue.