Нужна ли опция типа # seq <string>? - PullRequest
0 голосов
/ 27 августа 2018

Я обнаружил, что один параметр унаследованного кода имеет тип

#seq<string> option

и параметр используется как

for k,v in defaultHeaders |> Seq.filter(fun (k,_) -> 
    match headers with 
    | Some hs -> not(Seq.exists(fun y -> fst y = k) hs)
    | None -> true
    ) do
    client.DefaultRequestHeaders.Add(k, v)

Он может просто использовать Seq.empty для None параметра в коде. Есть ли допустимый вариант использования типа #seq<string> option? Что означает # в информации о типе?

1 Ответ

0 голосов
/ 27 августа 2018

Почему параметр seq option?

Одной из возможных причин для типа option в параметре является необязательные параметры в методе без каррирования (т. Е. В стиле кортежа). Если у вас есть параметр, объявленный как ?param, то он будет иметь тип Foo option, где Foo - это «нормальный» тип param (то есть тип, которым он был бы, если бы он не был необязательным параметром). ). Это позволяет вам писать код, подобный следующему (пример, дословно скопированный из документов MSDN):

type DuplexType =
    | Full
    | Half

type Connection(?rate0 : int, ?duplex0 : DuplexType, ?parity0 : bool) =
    let duplex = defaultArg duplex0 Full
    let parity = defaultArg parity0 false
    let mutable rate = match rate0 with
                        | Some rate1 -> rate1
                        | None -> match duplex with
                                  | Full -> 9600
                                  | Half -> 4800
    do printfn "Baud Rate: %d Duplex: %A Parity: %b" rate duplex parity

let conn1 = Connection(duplex0 = Full)
let conn2 = Connection(duplex0 = Half)
let conn3 = Connection(300, Half, true)

Здесь дополнительные параметры находятся в конструкторе типа Connection, но вы можете увидеть, как они работают. Что касается вашего конкретного вопроса о seq option параметрах, мне придется немного настроить пример документации MSDN, чтобы продемонстрировать разницу. Если один из этих необязательных параметров был последовательностью (скажем, последовательностью целых чисел, представляющих предпочтительные ставки и скорости восстановления), то вот как это может выглядеть с необязательными параметрами и без них:

type Connection(?rates : seq<int>) = // Final type will be `seq<int> option`
    let realRates = defaultArg rates Seq.empty
    let chosenRate = realRates |> Seq.find (fun r -> ...)

type ConnectionB(rates : seq<int>) = // Final type will be `seq<int>`
    let chosenRate = rates |> Seq.find (fun r -> ...)

let conn1 = Connection()  // Equivalent to passing `Seq.empty`
let conn2 = Connection(Seq.empty)
let conn3 = ConnectionB() // Compiler error; this is not allowed
let conn4 = ConnectionB(Seq.empty)

Использование необязательного параметра для seq позволяет вызывающей стороне пропускать указание этого параметра, что в некоторых случаях может сделать ваш API более привлекательным для использования. Так что это может быть одной из причин использовать seq option в параметре. В других случаях это не имеет смысла; все зависит от того, как вы хотите, чтобы ваш API смотрел на внешний код.

А как насчет # в объявлении типа?

Что касается вашего вопроса о символе #, он называется в документации MSDN гибких типов , и это сокращение для ограничения типа: объявление типа #Foo аналогично объявлению введите 'T when 'T :> Foo. Конкретное преимущество использования #seq состоит в том, что F # обычно неявно автоматически выполняет приведение между совместимыми типами и требует явного преобразования в ситуациях, подобных следующим (снова пример, дословно взятый из документов MSDN):

let iterate1 (f : unit -> seq<int>) =
    for e in f() do printfn "%d" e
let iterate2 (f : unit -> #seq<int>) =
    for e in f() do printfn "%d" e

// Passing a function that takes a list requires a cast.
iterate1 (fun () -> [1] :> seq<int>)

// Passing a function that takes a list to the version that specifies a
// flexible type as the return value is OK as is.
iterate2 (fun () -> [1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...