F# Static Member Type Constraints

前端 未结 3 1154
伪装坚强ぢ
伪装坚强ぢ 2020-12-02 23:39

I\'m trying to define a function, factorize, which uses structural type constraints (requires static members Zero, One, +, and /) similar to Seq.sum so that it can be used w

3条回答
  •  醉梦人生
    2020-12-03 00:04

    Firstly, here is a trivial example that shows how the syntax should look like:

    let inline zero< ^NUM when ^NUM : (static member get_Zero: unit-> ^NUM)> 
        (n:^NUM) = 
      (^NUM : (static member get_Zero : unit -> ^NUM) ())
    

    In some cases, you don't need to write the constraints explicitly (the F# compiler will actually warn you about that if you write the above), because some static members are well-known to the compiler and there are standard functions for using them. So, you can use the function and the compiler will infer the constraint:

    let inline zero (n:^T) = 
      LanguagePrimitives.GenericZero< ^T > 
    

    Unfortunately, this really doesn't help you, because recursive functions cannot be declared as inline (for obvious reasons - the compiler cannot inline the function at compile time, because it doesn't know how many times), so static constraints are probably not powerful enough for your problem.

    [EDIT: This is actually possible for some functions (see kvb's answer)]

    I think you'll need NumericAssociations instead, which were alreaday discussed in this question (these are processed at runtime, so they are slower - but are used to implement for example F# matrix type - the matrix can cache the dynamically obtained information, so it is reasonably efficient).

提交回复
热议问题