Search code examples
f#sequences

Scaling a sequence in F#


I am trying to scale a sequence by the first element of the sequence, so the first element will always be one, and then subsequent elements are a ratio of the first element to the nth element of the original sequence.

Here is my code,

       open System
       open System.Collections

           let squish1 (x:Double seq) =
                let r =  (Seq.head x:Double)
                Seq.fold (fun (xi:Double) (r:Double) -> xi/r);;

And I test on this little vector:-

                squish1 [|5.0; 1.0; 1.0; 1.0; 1.0; 1.0|];;

I have typed everything because I get this error message

normaliseSequence.fsx(9,1): error FS0030: Value restriction. The value 'it' has been >inferred to have generic type val it : (Double -> '_a -> Double) when '_a :> seq
Either make the arguments to 'it' explicit or, if you do not intend for it to be generic, >add a type annotation.

But clearly I am misunderstanding because I get the error message even with everything typed. What am I missing?

Any and all advice gratefully received. Thanks


Solution

  • fold expects two more parameters, the seed value and the sequence. This works:

    let squish1 (x:Double seq) =
        let r =  (Seq.head x:Double)
        Seq.fold (fun (xi:Double) (r:Double) -> xi/r) 0.0 x
    

    However, I'm guessing you probably want map instead of fold:

    let squish1 (x:Double seq) =
        let r =  (Seq.head x:Double)
        Seq.map (fun (xi:Double) -> xi/r) x
    

    Incidentally, I would probably write it this way:

    let inline squish1 (x:seq<_>) =
      let r = Seq.head x
      Seq.map (fun n -> n / r) x
    

    Now it works for all types that support division.