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 ```

Original source