Converting Haskell Polymorphic Cosine function to F#
f#, functional-programming, haskell, inline, polymorphism
Solution
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
Problem
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 ```