gpt4 book ai didi

f# - F# 中选项列表的选项列表

转载 作者:行者123 更新时间:2023-12-04 23:12:39 24 4
gpt4 key购买 nike

给定一个列表 [Some 1;一些 2; Some 3] 我想要一个输出 Some [1;2;3] 。给定一个列表 [Some 1;无] 应该产生无

我是 F# 的初学者,直到现在我已经完成了需要两个选项并创建一个列表选项的操作。我怎样才能制作一个选项列表来通过这个函数来获得结果?

let lift a b =
match a, b with
| Some av, Some bv -> Some[av;bv]
| _, _ -> None

lift (Some 2) None

最佳答案

在功能世界中,您所描述的通常称为 sequence .
这是围绕泛型类型的顺序交换的概念:

  • 来自 List<Option<int>>Option<List<int>>

  • 这是一个通用的方法:
    module Option =
    let (>>=) r f = Option.bind f r
    let rtn v = Some v

    let traverseList f ls =
    let folder head tail = f head >>= (fun h -> tail >>= (fun t -> h::t |> rtn))
    List.foldBack folder ls (rtn List.empty)
    let sequenceList ls = traverseList id ls

    // val traverseList : ('a -> 'b option) -> 'a list -> 'b list option
    // val sequenceList : 'a option list -> 'a list option

    这里 sequenceList类型签名为 'a option list -> 'a list option也可以表示为 List<Option<'a>> -> Option<List<'a>> .这正是您想要的。

    但是,但是,但是......与其他答案相比,这个答案似乎更加复杂。重点是什么?

    关键是这个解决方案是通用的,可以应用于任何一元(或应用)类型。例如与 Option 类似的泛型类型是 Result并且解决方案几乎和以前一样:
    module Result =
    let (>>=) r f = Result.bind f r
    let rtn v = Ok v

    let traverseList f ls =
    let folder head tail = f head >>= (fun h -> tail >>= (fun t -> h::t |> rtn))
    List.foldBack folder ls (rtn List.empty)
    let sequenceList ls = traverseList id ls

    // val traverseList : ('a -> Result<'b,'c>) -> 'a list -> Result<'b list,'c>
    // val sequenceList : Result<'a,'b> list -> Result<'a list,'b>

    看?除了第 2 行和第 3 行外,其余都是相同的。

    这使您可以抽象概念并将其放在您的脑海中。将来在您编程时,这将发生很多次,您需要迭代泛型类型,而类型最终会根据您的需要而反转。

    但是没有必要重新发明轮子。掌握如何创建的知识 sequence (和 traverse )你可以 Handlebars 伸进你的工具包里,并在需要任何 monadic 或应用程序类型的时候把它拉出来,无论是 Async , Result , Option , 等等。

    如果您想深入挖掘,请访问此网站,其中以清晰的图形和示例解释了概念: https://fsharpforfunandprofit.com/posts/elevated-world-4/

    关于f# - F# 中选项列表的选项列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53026410/

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