【问题标题】:F#: appending the value of an option to list optionF#:将选项的值附加到列表选项
【发布时间】:2019-04-01 13:26:46
【问题描述】:
我有一个基本的append 函数
let append item list = item :: list
我有一个'列表选项和选项Some("something")
let listOption = Some []
我想将值"something" 添加到listOption。如何在不使用模式匹配和Option.get 而是通过提升append 功能的情况下做到这一点?
任何帮助将不胜感激
【问题讨论】:
标签:
function
functional-programming
f#
lifting
【解决方案1】:
你可以使用也许计算表达式
type MaybeBuilder() =
member this.Bind(m, f) = Option.bind f m
member this.Return(x) = Some x
let maybe = new MaybeBuilder()
let append item list = item :: list
let appendLifted item list =
maybe {
let! l = list
let! i = item
return append i l
}
[<EntryPoint>]
let main argv =
appendLifted (Some "abc") (Some [])
0
【解决方案2】:
它看起来像一个家庭作业......
如果您想在列表选项的开头添加一个值(不是选项),您可以简单地执行此操作,如果列表选项为 None,则返回 None:
let liftedAppend item optList =
optList |> Option.bind (fun list -> Some (item :: list))
liftedAppend 签名为:
'a -> 'a list option -> 'a list option
但是谈论提升严格意义上的,因为您的附加功能的签名是:
'a -> 'a list -> 'a list
提升函数的签名应该是:
'a option -> 'a list option -> 'a list option
这意味着第一个参数必须是一个选项,我猜你想检查它是 Some 还是 None。如果是这样,请仔细阅读其他人的回复。
你可以使用这样的东西,去糖化 Lanayx 的计算表达式。
let liftedAppend optItem optList =
optList |> Option.bind (fun list ->
optItem |> Option.bind (fun item -> Some (item :: list)))
【解决方案3】:
这行得通:
listOption
|> Option.map (append 11)
|> printfn "%A" // Some [11]
但要创建一个提升的append:
let liftedAppend v = Option.map (append v)
listOption
|> liftedAppend 11
|> printfn "%A" // Some [11]
函数的签名是:
val append : 'a -> 'a list > 'a list
val liftedAppend: 'a -> 'a list option -> 'a list option
要将两个参数作为选项传递,您可以使用Option.map2:
let liftedAppend2 vO = vO |> Option.map2 append
listOption
|> liftedAppend2 (Some 11)
|> printfn "%A" // Some [11]
有签名的:
val liftedAppend2: a option -> 'a list option -> 'a list option