将Haskell多态余弦函数转换为F# [英] Converting Haskell Polymorphic Cosine function to F#
问题描述
我试图将一些Haskell代码转换为F#,但由于默认情况下Haskell是懒惰的,而F#没有,所以我遇到了一些麻烦。我还在学习围绕F#的方式。下面是Haskell中的多态余弦函数,具有相当不错的性能。我想尝试在F#中保持相同或更好的性能参数。我希望看到F#List版本和F#Seq版本,因为Seq版本更像是懒惰的Haskell,但List版本可能会表现更好。感谢您的帮助。
效率:用于与系列字数成比例的算术运算数量
空间:使用不变的空间,与术语数量无关
takeThemTwoByTwo xs =
takeWhile(not。null)[以2 ys | ys < - iterate(drop 2)xs]
产品xss = [产品xs | xs < - xss]
pairDifferences xs =
[foldr( - )0 adjacentPair | adjacentPair < - takeThemTwoByTwo xs]
谐波x = [x /(来自整数k)| k < - [1 ..]]
cosineTerms = scanl(*)1。产品。 takeThemTwoByTwo。谐波
cosine = foldl(+)0。 pairDifferences。
需要numberOfTerms。 cosineTerms
Pad的答案很好,但不是多态。一般来说,在F#中创建这样的定义比在Haskell中创建这种定义要少得多(并且有点痛苦)。这里有一种方法:
module NumericLiteralG =
let inline FromZero()= LanguagePrimitives。 GenericZero
let inline FromOne()= LanguagePrimitives.GenericOne
module ConstrainedOps =
let inline(〜 - )(x:^ a):^ a = -x
让内联(*)(x:^ a)(y:^ a):^ a =(x:^ a)(y:^ a):^ a = x + x * y
let inline(/)(x:^ a)(y:^ a):^ a = x / y
open ConstrainedOps
let内联余弦nx =
let two = 1G + 1G
Seq.unfold(fun(twoIp1,t) - > Some(t,(twoIp1 + two,-t * x * x /(twoIp1 * (twoIp1 + 1G)))))(1G,1G)
|> Seq.take n
|> Seq.sum
I'm trying to convert some Haskell code to F# but I'm having some trouble since Haskell is lazy by default and F# is not. I'm also still learning my way around F#. Below is a polymorphic cosine function in Haskell with pretty good performance. I want to try and keep the same or better performance parameters in F#. I would like to see a F# List version and a F# Seq version since the Seq version would be more like the lazy Haskell but the List version would probably perform better. Thanks for any help.
Efficiency: number of arithmetic operations used proportional to number of terms in series
Space: uses constant space, independent of number of terms
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
Pad's answer is good, but not polymorphic. In general, it's significantly less common to create such definitions in F# than in Haskell (and a bit of a pain). Here's one approach:
module NumericLiteralG =
let inline FromZero() = LanguagePrimitives.GenericZero
let inline FromOne() = LanguagePrimitives.GenericOne
module ConstrainedOps =
let inline (~-) (x:^a) : ^a = -x
let inline (+) (x:^a) (y:^a) : ^a = x + y
let inline (*) (x:^a) (y:^a) : ^a = x * y
let inline (/) (x:^a) (y:^a) : ^a = x / y
open ConstrainedOps
let inline cosine n x =
let two = 1G + 1G
Seq.unfold (fun (twoIp1, t) -> Some(t, (twoIp1+two, -t*x*x/(twoIp1*(twoIp1+1G))))) (1G,1G)
|> Seq.take n
|> Seq.sum
这篇关于将Haskell多态余弦函数转换为F#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!