2

假设有 atype r = {A : int; B : string; C : int; D : string}和 a 一些值:

let aOptional : int option = ...
let bOptional : string option = ...
let cOptional : int option = ...
let dOptional : string option = ...

怎么r optional能从它们优雅地构造出来(没有嵌套的 case-stuff 等)?


顺便说一句,这是如何在 haskell 中完成的Control.Applicative

data R = R { a :: Integer, b :: String, c :: Integer, d :: String}

R <$> aOptional <*> bOptional <*> cOptional <*> dOptional :: Maybe R

在 fsharp 中寻找等效的东西。

4

2 回答 2

5

The straightforward way is:

match aOptional, bOptional, cOptional, dOptional with
| Some a, Some b, Some c, Some d -> Some {A=a; B=b; C=c; D=d}
| _ -> None

or, with a maybe monad:

let rOptional = 
  maybe {
    let! a = aOptional
    let! b = bOptional
    let! c = cOptional
    let! d = dOptional
    return {A=a; B=b; C=c; D=d}
  }
于 2013-09-30T22:07:52.697 回答
5

我知道(使用应用程序)的唯一方法是创建一个函数来构造记录:

let r a b c d = {A = a; B = b; C = c; D = d}

然后你可以这样做:

> r </map/> aOptional <*> bOptional <*> cOptional <*> dOptional ;;

val it : R option

您可以自己定义map<*>但如果您想要一个通用实现,请尝试使用F#+的代码,或者如果您想直接使用FsControl,您可以这样编写代码:

#r "FsControl.Core.dll"

open FsControl.Operators

let (</) = (|>)
let (/>) f x y = f y x

// Sample code
type R = {A : int; B : string; C : int; D : string}
let r a b c d = {A = a; B = b; C = c; D = d}

let aOptional = Some 0
let bOptional = Some ""
let cOptional = Some 1
let dOptional = Some "some string"

r </map/> aOptional <*> bOptional <*> cOptional <*> dOptional
// val it : R option = Some {A = 0; B = ""; C = 1; D = "some string";}

更新Nuget 包现在可用。

于 2013-09-30T21:50:21.853 回答