我在C#中有一个函数,我想将它(在其他一些东西中)移植到F#,只是为了做到这一点.不幸的是,我只是遇到了一个似乎没有办法在F#中表达这种情况的案例:拿这个C#函数
public static T Min(params T[] p) where T : IComparable { T m1 = p[0]; foreach (T v in p) { m1 = (m1.CompareTo(v) < 0) ? m1 : v; } return m1; }
我认为这很容易,但我不明白如何在F#中指定变量参数列表.我试过这个:
let rec Min l =
match l with
| [] -> 0 // should throw exception here
| [v] -> v
| (h::t) -> min h (Min t)
但是从C#调用它需要一个Microsoft.FSharp.Collections.List
.有可能让它期待一个params T[]
,如果是这样,怎么样?
如Jon所说,params数组只是一个带属性的数组.在参数之前添加属性.
let test ([] arr : 'a array) =
if arr.Length = 0 then invalid_arg "arr"
// ....
您无需指定类型:
let test ([] arr) = ... // lets type inference do its thing
但是......模式匹配对数组类型不起作用.您可以编写一个活动模式来提供帮助.基本上,您必须决定什么更重要:F#代码或C#代码.当您设计高阶函数,使用元组,使用有区别的联合等时,同样的权衡将适用.C#不能表达大多数事物,而F#目前不支持C#中的一些小部分(表达式树写入例如,编译器).
你想从F#或C#调用这个方法吗?这个hubFS帖子似乎表明F#不支持调用端的参数数组,但是我怀疑如果你为参数使用普通类型注释使它成为一个数组,并且还用ParamArrayAttribute来装饰它,你应该能够用C#中的变量参数调用它.
不能说我已经看过如何使用F#中的属性来装饰一个参数,但是如果你想要的话我可以寻找... 这个博客文章提供了几个例子,但不是在参数级别.