gpt4 book ai didi

f# - 避免使用 Option.Value

转载 作者:行者123 更新时间:2023-12-01 09:25:29 26 4
gpt4 key购买 nike

我有一个这样的类型:

type TaskRow =
{
RowIndex : int
TaskId : string
Task : Task option
}

函数返回这些记录的列表以进一步处理。执行该处理的某些函数仅与 TaskSomeTaskRow 项相关。我想知道最好的方法是什么。

天真的方法会做

let taskRowsWithTasks = taskRows |> Seq.filter (fun row -> Option.isSome row.Task)

并将其传递给那些函数,简单地假设 Task 永远不会是 None 并使用 Task.Value,如果我冒着 NRE 的风险不要传入那个特殊的列表。这正是当前 C# 代码所做的,但对于 F# 来说似乎相当单一。我不应该“假设”事情,而是让编译器告诉我什么会起作用。

更多的“功能”将是每次值相关时进行模式匹配,然后对 None 不做/不返回任何内容(并使用 choose 等),但是这似乎是重复和浪费的,因为同样的工作会被多次完成。

另一个想法是引入第二种略有不同的类型:

type TaskRowWithTask =
{
RowIndex : int
TaskId : string
Task : Task
}

然后将原始列表过滤成这种类型的“子列表”,以便在适当的地方使用。从功能的角度来看,我想这没问题,但我想知道是否有更好的、惯用的方式而不求助于这种“辅助类型”。

感谢您的指点!

最佳答案

知道任务已经被过滤是很有值(value)的,所以有两种不同的类型会很有帮助。除了定义两种不同的类型(虽然在 F# 中这没什么大不了的),您还可以考虑定义一个泛型 Row类型:

type Row<'a> = {
RowIndex : int
TaskId : string
Item : 'a }

这使您可以像这样定义投影:

let project = function
| { RowIndex = ridx; TaskId = tid; Item = Some t } ->
Some { RowIndex = ridx; TaskId = tid; Item = t }
| _ -> None

let taskRowsWithTasks =
taskRows
|> Seq.map project
|> Seq.choose id

如果初始 taskRows值的类型为 seq<Row<Task option>> ,然后得到 taskRowsWithTasks序列的类型为 seq<Row<Task>> .

关于f# - 避免使用 Option.Value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25463644/

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