在F#中,我有一个带签名type func= (string-> string list) option
的可选功能。如何将签名type param= string option
的可选字符串参数传递给func
方法。
如果不使用嵌套的if else,有没有办法做到这一点。
答案 0 :(得分:2)
我没有立即注意到函数本身也包裹在option
中。我会将以下误读问题的原始答案保留以供参考,但这里是实际问题的答案:
首先,当没有功能和/或没有字符串时,你仍然需要决定你想做什么(见下文)。一旦你做出决定,你就可以匹配元组:
let resultingList =
match func, param with
| Some f, Some p -> f p // When both are present, apply
| _ -> [] // Otherwise, return empty list
在这里,当任何一个或两个都缺席时,我会崩溃。但是,如果您需要针对这些情况采用不同的行为,则可以明确地枚举其中的全部或部分内容:
let resultingList =
match func, param with
| Some f, Some p -> f p
| Some f, None -> f ""
| None, Some _ -> [ "there was no function" ]
| None, None -> [ "there was no string AND no function" ]
类型string option
表示" 此处可能有字符串,或者"。所以问自己的第一个问题是:当没有字符串时你想做什么?我无法帮助你决定这一点,因为这取决于你的大问题(即你最终要做的事情)。
功能string -> string list
需要string
并返回string list
。因此,如果您有一个字符串,那么您将获得string list
。但是如果你没有string
怎么办?如果你没有得到什么" (即"没有列表",就像"没有字符串"开头)?或者你应该得到一个空列表?或者你应该得到一些预定值吗?
为了逐步学习,让我们假设,当没有字符串时,你想要找回一个空列表。为此,请使用模式匹配:
let resultingList =
match param with
| Some s -> func s
| None -> []
这个程序字面上说:" 如果有字符串,则调用该字符串s
并对其应用func
;如果没有字符串,则返回一个空列表"。
同样的事情适用于获取其他预定义列表而不是空列表:
let resultingList =
match param with
| Some s -> func s
| None -> [ "oopsie, there was no string!" ]
但如果你想要另一个选项 - "没有列表"一, - 那么您的结果值必须为string list option
,就像您的输入为string option
一样。 option
类型有两个构造函数:Some
用于创建存在的值,None
用于表示"没有 spoon 值"
let maybeResultingList =
match param with
| Some s -> Some (func s)
| None -> None
字面上说:" 如果有字符串,则调用它s
,将func
应用于它,并将结果包装为Some
,这意味着"这里有一个列表&#34 ;;如果没有字符串,只需返回None
,这意味着"没有列表"。
幸运的是,这个" 将函数应用于该值,除非它不存在"操作是如此常见,以至于它有一个标准的库函数。它被称为Option.map
:
let maybeResultingList = Option.map func param
另一个有趣的方法是:首先我们将func
传递给Option.map
并返回另一个函数,然后我们将该函数应用于param
:
let maybeFunc = Option.map func
let maybeResultingList = maybeFunc param
这种看待它的方式在实践中非常有用。令人尊敬的Scott Wlaschin在这个概念上有一个非常棒的系列。请在此处查看:https://fsharpforfunandprofit.com/posts/elevated-world/