我正在尝试将一些Haskell代码转换为F#,但我遇到了一些麻烦,因为Haskell默认是懒惰而F#不是.我还在学习F#的方式.下面是Haskell中的多态余弦函数,具有相当好的性能.我想尝试在F#中保持相同或更好的性能参数.我希望看到一个F#List版本和一个F#Seq版本,因为Seq版本更像是懒惰的Haskell,但List版本可能会表现得更好.谢谢你的帮助.
效率:使用的算术运算数与串联项数成比例
空间:使用恒定空间,与术语数量无关
takeThemTwoByTwo xs =
takeWhile (not . null) [take 2 ys | ys <- iterate (drop 2) xs]
products xss = [product xs | xs <- xss]
pairDifferences xs =
[foldr (-) 0 adjacentPair | adjacentPair <- takeThemTwoByTwo xs]
harmonics x = [x/(fromIntegral k) | k <- [1 ..]]
cosineTerms = scanl (*) 1 . products . takeThemTwoByTwo . harmonics
cosine = foldl (+) 0 . pairDifferences .
take numberOfTerms . cosineTerms
Run Code Online (Sandbox Code Playgroud) 没有类型规范,F#函数定义似乎只接收int类型.我不想使用泛型编程,只想声明一个函数来接收2个浮点类型,将它们加在一起:
> let g a b=a+b;;
val g : a:int -> b:int -> int
Run Code Online (Sandbox Code Playgroud)
如何改变我的陈述?谢谢.
我在F#中做Project Euler问题1:
3和5的倍数
如果我们列出10以下的所有自然数是3或5的倍数,我们得到3,5,6和9.这些倍数的总和是23.
求出1000以下3或5的所有倍数的总和.
这是我的尝试:
[1..999]
|> List.filter (fun x -> x%3 * x%5 = 0)
|> List.sum
val it : int = 233168
Run Code Online (Sandbox Code Playgroud)
我的朋友在Excel中通过添加3的倍数和5的倍数提取15的倍数来计算它,并且他用更大的上限来挑战我:找到1234567以下的所有3或5的倍数的总和.
我试过这个:
[1..1234567]
|> List.filter (fun x -> x%3 * x%5 = 0)
|> List.sum
Run Code Online (Sandbox Code Playgroud)
System.OverflowException:算术运算导致溢出.
第二次尝试:
let mutable result = 0
for x < 1000 do
if x%3 * x%5 = 0 then result = result + x
Run Code Online (Sandbox Code Playgroud)
错误FS0010:模式中出现意外的整数文字.预期的中缀运算符,引号或其他标记.
令我惊讶的是,Python可以很好地处理这个并且效率很高:
sum(x for x in range(1234567) if x%3 * x%5 == 0)
# 355636612814L …Run Code Online (Sandbox Code Playgroud) 我仍然无法理解为什么我会将关键字inline用于函数.
它给了我什么,我还没有?
let inline (|Positive|Neutral|Negative|) x =
match sign x with
| 1 -> Positive
| -1 -> Negative
| _ -> Neutral
Run Code Online (Sandbox Code Playgroud) 我正在尝试定义以下函数(在Seq模块名称中共享空间).
module Seq =
let scale value sequence =
sequence
|> Seq.map (fun v -> v * value)
Run Code Online (Sandbox Code Playgroud)
然而,类型推断强加元素和值是类型int.我希望这个方法可以处理整数(8位,16位等),浮点数(单和双)等.
为什么类型推断会跳转到int,以及如何使此函数更通用?