我对F#很陌生,发现类型推断确实很酷.但目前似乎它也可能导致代码重复,这不是一件很酷的事情.我想总结一个这样的数字的数字:
let rec crossfoot n =
if n = 0 then 0
else n % 10 + crossfoot (n / 10)
crossfoot 123
Run Code Online (Sandbox Code Playgroud)
这正确打印6.但是现在我的输入数字不适合32位,所以我必须将其转换为.
let rec crossfoot n =
if n = 0L then 0L
else n % 10L + crossfoot (n / 10L)
crossfoot 123L
Run Code Online (Sandbox Code Playgroud)
然后,BigInteger我来了,猜猜是什么......
当然,我只能提供bigint版本和转换输入参数,并根据需要输出参数.但首先我假设使用BigInteger过度int有一些性能惩罚.第二个let cf = int (crossfoot (bigint 123))不好看.
写这个没有通用的方法吗?
考虑这个F#代码,将下面的数字相加i为3和5的倍数:
let isMultipleOfThreeOrFive n =
(n % 3 = 0) || (n % 5 = 0)
let sequenceOfMultiples i =
seq {1 .. i - 1} |> Seq.filter isMultipleOfThreeOrFive
Run Code Online (Sandbox Code Playgroud)
因为i是int,如果i很大,你会溢出.这个版本BigInteger负责:
let isMultipleOfThreeOrFive n =
(n % 3I = 0I) || (n % 5I = 0I)
let sequenceOfMultiples (i : System.Numerics.BigInteger) =
seq {1I .. i - 1I} |> Seq.filter isMultipleOfThreeOrFive
Run Code Online (Sandbox Code Playgroud)
要将int版本转换为版本BigInteger,我必须I在数字后添加许多s.这是因为F#不进行隐式转换.
有没有一种简单的方法来解决这个问题,或者I在6个地方添加s是最好的办法?
我在F#中编写了一个提供一些按位操作的库¹,我想确保尽可能多的函数是inline使用静态类型参数进行绑定(这允许我编写一个函数并将其用于int16,int32也许甚至bignum只有很少的开销).这条路线肯定无法在某些时候起作用.所述库提供的一些功能有些复杂.
¹注意:我知道通过公共接口公开内联let绑定的问题.
但是,我想把它延伸到最远的程度.现在,我正在尝试以这种形式编写人口计数算法,我正面临一个问题.我不确定如何对掩码进行编码,例如0x3333...,这些算法中出现的掩码.我可以使用一些额外的技巧来绕过移位常数和类似的东西.
有没有我可以使用的技巧,无论是通过F#的类型推断和静态类型参数,还是通过bit-twiddling,以我想要的方式编写算法?有没有什么办法可以在静态泛型函数中编码这些常量?
一个更模糊的问题:我是否可以依赖一些特定的东西来充分利用静态类型参数,尤其是在数值的背景下?例如,我大量使用GenericOne和GenericZero.还有更多这样的事情,我可能错过了吗?
我写了一个简单的函数来反转给定的数字:
let reverseNumber x =
let rec innerFunc acc elem =
if elem = 0
then acc
else
let rem = elem % 10
innerFunc (10 * acc + rem) (elem / 10)
innerFunc 0 x
Run Code Online (Sandbox Code Playgroud)
问题是它只适用于整数.对于例如,Int64的,我需要创建一个使用另一个版本0L,并10L取代0和10分别.
我听说可以使用内联关键字和LanguagePrimitives编写更多泛型函数,但后者既不包含提醒操作也不包含'GenericTen'(尽管可能通过'GenericOne + GenericOne + ...获得).
你能帮忙吗 ?