gpt4 book ai didi

f# - 可选地获取序列中的第一项

转载 作者:行者123 更新时间:2023-12-03 14:55:48 25 4
gpt4 key购买 nike

我需要一个像 Seq.head 这样的函数, 但返回 None而不是在序列为空时抛出异常,即 seq<'T> -> 'T option .

有很多方法可以做到这一点。这里有几个:

let items = Seq.init 10 id
let a = Seq.tryFind (fun _ -> true) items
let b = Seq.tryPick Some items
let c = if Seq.isEmpty items then None else Some (Seq.head items)
let d =
use e = items.GetEnumerator()
if e.MoveNext() then Some e.Current
else None
b是我使用的那个。两个问题:
  • 有没有特别惯用的方法来做到这一点?
  • 由于没有内置 Seq.tryHead函数,这是否表明这不是必需的、不常见的,或者没有函数更好地实现?

  • 更新
    tryHead has been added to the standard library in F# 4.0 .

    最佳答案

    我认为 (b) 可能是最惯用的,原因与@Ramon 给出的相同。

    我认为缺少Seq.tryHead只是意味着它不是 super 常见的。

    我不确定,但我的猜测是,具有 Hindley-Milner 类型推断的函数式语言通常很少在集合类型上实现此类特定函数,因为重载不可用并且可以简洁地编写高阶函数。

    例如,C# Linq 扩展比 F# 的 Seq 中的函数更详尽。模块(它本身比具体集合类型上的函数更详尽),甚至有 IEnumerable.FirstOrDefault .实际上,每个过载都有一个变体,它执行 map .

    我认为强调模式匹配和具体类型,如 list也是一个原因。

    现在,以上大部分都是猜测,但我想我可能有一个更接近客观的概念。我想很多时候tryPicktryFind可以首先使用而不是 filter |> tryHead .例如,我发现自己经常编写如下代码:

    open System.Reflection
    let ty = typeof<System.String> //suppose this type is actually unknown at compile time
    seq {
    for name in ["a";"b";"c"] do
    yield ty.GetMethod(name)
    } |> Seq.tryFind((<>)null)

    而不是喜欢
    ...
    seq {
    for name in ["a";"b";"c"] do
    match ty.GetMethod(name) with
    | null -> ()
    | mi -> yield mi
    } |> tryHead

    关于f# - 可选地获取序列中的第一项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7487541/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com