将Haskell多态余弦函数转换为F# [英] Converting Haskell Polymorphic Cosine function to F#

查看:120
本文介绍了将Haskell多态余弦函数转换为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆