如何在F#中乘以两个(双选项)s

Dut*_*tts 5 monads f#

我的代码包含了很多双选项类型; 到目前为止,我一直非常成功地使用Option.map函数,以消除在所有地方匹配Some和None并将它们视为提升类型的需要,但我不确定在以下场景中该怎么做:

let multiplyTwoOptions option1 option2 : double option =
  if not (option1.IsSome && option2.IsSome) then None
  else Some (option1.Value * option2.Value)
Run Code Online (Sandbox Code Playgroud)

我已经读过你不应该以这种方式使用IsSome,但另一种选择(据我所知,顺序上的模式匹配,似乎很长时间).我对F#还是很陌生,所以想知道是否有更惯用的方式?我觉得我可能需要像Option.fold2这样的东西同时对两个选项起作用,但没有一个.

Fyo*_*kin 10

模式可以嵌套,这是它们的强大功能.在这种特殊情况下,您可以在元组上进行模式匹配:

match option1, option2 with
| Some x, Some y -> Some (x * y)
| _ -> None
Run Code Online (Sandbox Code Playgroud)


Hel*_*olm 9

正确答案实际上如下:

https://fsharpforfunandprofit.com/posts/elevated-world/#apply

如果需要一些代码,那么归结为以下示例:

module Option =

    // The apply function for Options
    let apply fOpt xOpt = 
        match fOpt,xOpt with
        | Some f, Some x -> Some (f x)
        | _ -> None


let (<!>) = Option.map
let (<*>) = Option.apply

let a = Some(4)
let b = Some(5)

let  multiplication = (*)

//Some multiplication function applied on a and resulting function applied on b
let res1 = Some(multiplication) <*> a <*> b
let res2 = Some(*) <*> a <*> b

//Map a onto multiplication function and resulting function applied on b
let res3 = multiplication <!> a <*> b
let res4 = (*) <!> a <*> b


val res1 : int option = Some 20
val res2 : int option = Some 20
val res3 : int option = Some 20
val res4 : int option = Some 20

//The following is without any options to try to clarify the above

let op = (*) //multiplication
//let partialRes = (*) 4
let partialRes = op 4 //make function for multiplying param with 4
let fullres = partialRes 5 //use function for multiplying with 4

val op : (int -> int -> int)
val partialRes : (int -> int)
val fullres : int = 20
Run Code Online (Sandbox Code Playgroud)

说这个的原因是,上面的内容可以在Wlaschin所谓的"提升世界"或者在这种情况下选择两种方式之间进行混合.的种类.阅读Wlaschin撰写的完整网站或书籍.

没有必要将选项作为参数进行任何功能,并且可以一劳永逸地处理包装和展开.

正如上面的代码所示(从链接中无耻地窃取,并在某种程度上被重写),理查德需要的功能是:

Option.apply
Run Code Online (Sandbox Code Playgroud)

是的,这些符号可能会混淆,因为我们正在讨论乘法或*这里,但map <!>和apply <*>的这些符号有些"标准".

我认为代码中的注释在如何阅读代码方面或多或少是正确的.

是的,我可能需要研究我的教学风格;-)

  • 我不会在同一句话中使用'grok'和'minute'这个词;-)尤其不是这个主题.我仍然不理睬它,需要仔细考虑每一个细节,以确保我做对了.然后我总是想知道:我做对了吗......这篇文章是为了帮助我解决... (2认同)
  • 不确定我是否会称之为**正确答案.应用函子几乎不属于F#课程. (2认同)