generics - 将 F# 泛型函数参数约束为整型

标签 generics f#

假设我正在构造一个带有单个参数 integral 的 F# 泛型函数 f,并且函数语义的该参数应限制为任何 .NET 整数类型从 System.SByteSystem.Int32System.Numerics.BigInteger

一种方法是实现

let inline f (integral: 'a) =
    (* function body here *) ...

并依赖于从 f 主体的实际内容派生的编译器推导的对 'a 的约束,该约束可能与整套整型一致,也可能不一致。网 类型。

另一种方法可能是强制对 'a 显式手工选择先验约束,这将真正保证已知的 .NET 类型只有整型类型传递静态 例如检查

let inline f (integral: ^a when ^a:(static member (|||): ^a * ^a-> ^a)) =
    (* function body here, unit for illustration *)()

let inline f< ^a when ^a : (static member (|||): ^a * ^a -> ^a)> (integral: ^a) =
    (* function body here, unit for illustration *)()

so f 1uyf 1Lf 1I 立即通过静态类型检查,但 f 'a'f 1.0f 1m 没有。

使用第二种方法相对于第一种方法有什么好处(如果有的话)?

是否有更惯用的方法来实现最初的目标?

更新 02/03/2014 讽刺的是,直到今天才查看 this answer设法从 @kvb's prompt 中获取工作代码:

let inline implementation integral = ((* whatever implementation here *)) 

type Integral = Integral with 
    static member ($) (Integral, value: byte) = implementation value
    static member ($) (Integral, value: sbyte) = implementation value
    static member ($) (Integral, value: int16) = implementation value
    static member ($) (Integral, value: uint16) = implementation value
    static member ($) (Integral, value: int) = implementation value
    static member ($) (Integral, value: uint32) = implementation value
    static member ($) (Integral, value: int64) = implementation value
    static member ($) (Integral, value: uint64) = implementation value
    static member ($) (Integral, value: bigint) = implementation value

let inline doit integral = Integral $ integral

doit 1
doit 1I
doit 1.0 // does not compile
doit 1.0m // does not compile
doit '1' // does not compile

最佳答案

如果您确实只想将可能性限制为整数类型,那么使用重载静态方法将是一种选择。为了减少代码重复,这些都可以通过不受限制的通用函数来实现。

关于generics - 将 F# 泛型函数参数约束为整型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16737675/

相关文章:

java - Java 通配符类型的下限和上限

c# - 通用 IList<T> 的 "type"是什么?

mysql - 来自数据库的 Deedle Frame,什么是 Schema?

f# - 如何在 F# 中将两个(双选项)相乘

c# - .NET 是否具有字符实体及其 unicode 值之间的内置函数映射?

f# - 在 F# 中没有值的成员

.net - 在 .NET 中,Array 只扩展了 IEnumerable,那么当 foreach 循环经过值类型数组时,是否会有装箱和拆箱?

c# - 后代非泛型类到基泛型类

c# - 如何使 GlyphTypeface FontUri 通用

f# - 如何模仿 F# 编译器类型检查?