具有泛型参数类型的函数 [英] Functions with generic parameter types

查看:34
本文介绍了具有泛型参数类型的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚如何定义一个可以处理多种类型参数(例如 int 和 int64)的函数.据我了解,在 F# 中函数重载是不可能的(当然编译器会抱怨).以下面的函数为例.

I am trying to figure out how to define a function that works on multiple types of parameters (e.g. int and int64). As I understand it, function overloading is not possible in F# (certainly the compiler complains). Take for example the following function.

let sqrt_int = function
    | n:int   -> int (sqrt (float n))
    | n:int64 -> int64 (sqrt (float n))

编译器当然会抱怨语法无效(似乎不支持模式匹配中的类型约束),尽管我认为这说明了我想要实现的目标:一个对多个参数类型进行操作并返回值的函数相应类型的.我有一种感觉,这在 F# 中使用泛型类型/类型推断/模式匹配的某种组合是可能的,但语法让我望而却步.我也试过使用 :?运算符(动态类型测试)和模式匹配块中的 when 子句,但这仍然会产生各种错误.

The compiler of course complains that the syntax is invalid (type constraints in pattern matching are not supported it seems), though I think this illustrates what I would like to achieve: a function that operates on several parameter types and returns a value of the according type. I have a feeling that this is possible in F# using some combination of generic types/type inference/pattern matching, but the syntax has eluded me. I've also tried using the :? operator (dynamic type tests) and when clauses in the pattern matching block, but this still produces all sorts errors.

由于我对这门语言还很陌生,我很可能会在这里尝试做一些不可能的事情,所以如果有其他解决方案,请告诉我.

As I am rather new to the language, I may very well be trying to do something impossible here, so please let me know if there is alternative solution.

推荐答案

重载通常是类型推断语言的麻烦事(至少当像 F# 一样,类型系统不足以包含类型类时).在 F# 中有许多选择:

Overloading is typically the bugaboo of type-inferenced languages (at least when, like F#, the type system isn't powerful enough to contain type-classes). There are a number of choices you have in F#:

  • 对方法(类型的成员)使用重载,在这种情况下,重载的工作方式与其他 .Net 语言非常相似(您可以临时重载成员,前提是可以通过参数的数量/类型区分调用)
  • 使用内联"、^"和静态成员约束对函数进行临时重载(这是大多数需要处理 int/float/等的各种数学运算符的内容;这里的语法很奇怪,除了 F# 库之外很少使用)
  • 通过传递额外的操作字典参数来模拟类型类(这是 Inumeric 在 F# PowerPack 库之一中所做的,用于为任意用户定义的类型概括各种数学算法)
  • 回退到动态类型(传入obj"参数,进行动态类型测试,为错误类型抛出运行时异常)

对于您的特定示例,我可能只会使用方法重载:

For your particular example, I would probably just use method overloading:

type MathOps =
    static member sqrt_int(x:int) = x |> float |> sqrt |> int
    static member sqrt_int(x:int64) = x |> float |> sqrt |> int64

let x = MathOps.sqrt_int 9
let y = MathOps.sqrt_int 100L

这篇关于具有泛型参数类型的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆