我试图弄清楚如何定义一个适用于多种类型参数的函数(例如int和int64).据我了解,F#中无法实现函数重载(当然编译器会抱怨).以下面的功能为例.
let sqrt_int = function
| n:int -> int (sqrt (float n))
| n:int64 -> int64 (sqrt (float n))
Run Code Online (Sandbox Code Playgroud)
编译器当然抱怨语法无效(似乎不支持模式匹配中的类型约束),尽管我认为这说明了我想要实现的内容:一个对多个参数类型进行操作并返回相应值的函数类型.我觉得在F#中使用泛型类型/类型推断/模式匹配的某种组合是可能的,但语法已经躲过了我.我也尝试过使用:?操作者(动态型测试)和当在模式匹配块子句,但这仍然会产生各种错误.
由于我对这门语言不熟悉,我很可能会尝试在这里做一些不可能的事情,所以如果有其他解决方案,请告诉我.
我正在尝试定义一个函数,factorize,它使用类似于Seq.sum的结构类型约束(需要静态成员Zero,One,+和/),以便它可以与int,long,bigint等一起使用.I似乎无法获得正确的语法,并且无法在该主题上找到很多资源.这就是我所拥有的,请帮助.
let inline factorize (n:^NUM) =
^NUM : (static member get_Zero: unit->(^NUM))
^NUM : (static member get_One: unit->(^NUM))
let rec factorize (n:^NUM) (j:^NUM) (flist: ^NUM list) =
if n = ^NUM.One then flist
elif n % j = ^NUM.Zero then factorize (n/j) (^NUM.One + ^NUM.One) (j::flist)
else factorize n (j + ^NUM.One) (flist)
factorize n (^NUM.One + ^NUM.One) []
Run Code Online (Sandbox Code Playgroud) 真的很遗憾,在.Net中没有数字的多态性,即没有统一不同类型的数字类型的数字接口,如bool,byte,uint,int等.在极端情况下,我们想要一个完整的抽象包代数类型.
Joe Duffy有一篇关于这个问题的文章:
http://www.bluebytesoftware.com/blog/CommentView,guid,14b37ade-3110-4596-9d6e-bacdcd75baa8.aspx
您如何在C#中表达这一点,以便在不影响.Net或C#的情况下对其进行改造?
我有一个想法,首先要定义一个或多个抽象类型(接口,如INumeric - 或者比它更抽象),然后定义实现这些的结构并包装类型如int,同时提供返回新类型的操作(例如Integer32: INumeric;其中添加将被定义为
public Integer32 Add(Integer32 other)
{
return Return(Value + other.Value);
}
Run Code Online (Sandbox Code Playgroud)
我有点害怕这段代码的执行速度,但至少它是抽象的.
没有运营商超载良好......
还有其他想法吗?
.Net看起来不像一个可行的长期平台,如果它不能拥有我认为的这种抽象 - 并且效率很高.
抽象是重用.
更新:
到目前为止,这是一个示例实现类型签名:
public struct Integer32 : INumeric<Integer32, Int32>, IOrder<Integer32, Int32>
Run Code Online (Sandbox Code Playgroud)
补偿缺乏协变返回类型.
假设我正在解决一个特定的问题并提出一个函数
let function parameter1 ... =
a lot of adding, multiplying & so on with a lot of
literals all over the place
Run Code Online (Sandbox Code Playgroud)
现在,如果我的参数是 int 类型,这个函数就可以正常工作。但是在某个地方我需要将它提升到 11,我需要额外推动 int64 甚至 BigInteger。那我该怎么办?我复制并粘贴函数,更改名称,并寻找所有使编译器认为函数应该在 int 上运行的文字外观。这很糟糕。
有没有办法做到这一点:
let greatFunction param1 param2 = (param1+1)/(param2*2)
Run Code Online (Sandbox Code Playgroud)
其中 param1 和 param2 可以是整数类型的任何组合?
编辑:
通过下面的 kvb 对一个很棒的提示进行了扩展,我想出了以下内容
module NumericLiteralG
let inline FromZero() = LanguagePrimitives.GenericZero
let inline FromOne() = LanguagePrimitives.GenericOne
let inline FromInt32 n =
let rec loop nIn nOut =
if nIn>0 then loop (nIn - 1) (nOut + …Run Code Online (Sandbox Code Playgroud) 今天我用F#玩了一下,写道:
let sq x = x * x
let i = sq 3
let d = sq 3.0
Run Code Online (Sandbox Code Playgroud)
如果我删除第三行或第四行,它会编译,但如果两者都存在则不会编译.
我收到了错误This expression should have type 'int', but has type 'float'.
我是F#的初学者.我知道有使用PowerPack.dll创建Double Matrix的方法:
let B = matrix [ [ 1.0; 7.0 ];
[ 1.0; 3.0 ] ]
Run Code Online (Sandbox Code Playgroud)
如何使用我自己的类型的元素创建矩阵(例如使用[,]而不是Double),所以它看起来像:
let B = matrix [ [ [1,2]; [3,4] ];
[ [7,8]; [5,6] ] ]
Run Code Online (Sandbox Code Playgroud) 我刚刚开始使用F#,但我有一些类似于以下内容的代码:
let square x = x*x
let result = square 5.1
let result' = square 12
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会导致以下错误: This expression was expected to have type float but here has type int
这个问题是否有惯用的F#解决方案,还是我的想法被我的C#体验所污染?
f# ×6
inline ×3
generics ×2
.net ×1
abstraction ×1
c# ×1
constraints ×1
matrix ×1
numeric ×1
overloading ×1
performance ×1
typeclass ×1
types ×1