Масштабирование последовательности в F #

Я пытаюсь масштабировать последовательность по первому элементу последовательности, поэтому первый элемент всегда будет один, а затем последующие элементы представляют собой отношение первого элемента к n-му элементу исходной последовательности.

Вот мой код,

       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);;

И я тестирую этот маленький вектор: -

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

Я все ввел, потому что получаю это сообщение об ошибке

normaliseSequence.fsx (9,1): ошибка FS0030: ограничение значения. > Предполагается, что значение 'it' имеет универсальный тип val it: (Double -> '_a -> Double) when' _a:> seq
Либо сделайте аргументы для 'it' явными, либо, если вы этого не сделаете намереваясь сделать его универсальным,> добавьте аннотацию типа.

Но очевидно, что я неправильно понимаю, потому что я получаю сообщение об ошибке даже при вводе всего текста. Что мне не хватает?

Любые и все советы получены с благодарностью. Спасибо


person Simon Hayward    schedule 25.10.2011    source источник
comment
Обратите внимание, что в F # более идиоматично использовать псевдоним float, а не System.Double.   -  person kvb    schedule 25.10.2011
comment
Да, я знаю. Это был выбор нашей команды разработчиков из-за типов данных, которые нам иногда приходится обрабатывать.   -  person Simon Hayward    schedule 25.10.2011
comment
Но float - это просто псевдоним для System.Double. Это одно и то же. kvb просто говорит, что более идиоматично использовать псевдоним float в вашем коде - это ничего не меняет в поведении вашей программы.   -  person Joel Mueller    schedule 26.10.2011
comment
Интересно, передам ваши комментарии ведущему разработчику.   -  person Simon Hayward    schedule 26.10.2011


Ответы (1)


fold ожидает еще два параметра: начальное значение и последовательность. Это работает:

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

Однако я предполагаю, что вы, вероятно, захотите map вместо fold:

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

Кстати, я бы, наверное, написал так:

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

Теперь это работает для всех типов, поддерживающих разделение.

person Daniel    schedule 25.10.2011
comment
Спасибо за совет. Теперь я просто получаю 0,0 в качестве ответа! Я надеялся на масштабную последовательность? Я использую неправильную функцию (.fold)? - person Simon Hayward; 25.10.2011
comment
Да, это звучит прямо сейчас. Я избавился от | ›Seq.skip 1, поскольку это означало, что первый термин был пропущен, но теперь это работает, как ожидалось. Большое спасибо. - person Simon Hayward; 25.10.2011
comment
Ой, только что видел исправленную версию. Это очень аккуратно. - person Simon Hayward; 25.10.2011
comment
Ха-ха, теперь он делит r на члены x, поэтому он дает обратные ответы, которые я хочу! - person Simon Hayward; 25.10.2011
comment
Ой, ты прав. Вам придется использовать Seq.map (fun n -> n / r) x - person Daniel; 25.10.2011
comment
Спасибо. Выше и вне служебного долга есть :) - person Simon Hayward; 25.10.2011