Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何重写多级匹配表达式_F# - Fatal编程技术网

F# 如何重写多级匹配表达式

F# 如何重写多级匹配表达式,f#,F#,我有返回a'选项的函数type。我有如下函数: let foo(a) = match fooB a.F1 with | Some(b) -> match fooC b.F2 with | Some(c) -> match fooD c.F3 with | Some(d) -> match fooE d.F4 with

我有返回
a'选项的函数
type。我有如下函数:

let foo(a) = 
   match fooB a.F1 with
   | Some(b) -> match fooC b.F2 with
                | Some(c) -> match fooD c.F3 with 
                             | Some(d) -> match fooE d.F4 with 
                                          // ......
                             | None -> ()
                | None -> ()
    | None -> ()

是否有任何功能模式可以避免这种多级
匹配表达式

似乎您正在寻找的是
选项。bind

let foo(a) = 
    fooB a.F1 
    |> Option.bind(fun b -> fooC b.F2)
    |> Option.bind(fun c -> fooD c.F3)
    |> Option.bind(fun d -> fooE d.F4)
Option.bind
基本上等同于

// ('a -> 'b option) -> 'a option -> 'b option
let bind f m =
    match m with
    | Some x -> f x
    | _ -> None

函数式编程可以利用一元操作,特别是
bind
操作符。下面是它在上的使用说明,它来自Haskell,但与F#的
选项
类型相同

幸运的是,
bind
操作符几乎是预定义的:

let (>>=) ma f = Option.bind f ma

let foo a = 
    fooB a.F1
    >>= fun b -> fooC b.F2 
    >>= fun c -> fooD c.F3 
    >>= fun d -> fooE d.F4
    // ...

另一个选项是利用
option.bind
函数为选项类型创建计算表达式生成器

type OptionBuilder() =
    member __.Bind (opt,map) = Option.bind map opt
    member __.Return value = Some value
    member __.ReturnFrom (opt: Option<_>) = opt
    member __.Zero () = Some ()

let option = OptionBuilder()
如果所有选项都是
Some
,则将返回
d.F4的
Some
,否则将返回
None

let foo a =
    option {
        let! b = fooB a.F1
        let! c = fooC b.F2
        let! d = fooD c.F3
        return! fooE d.F4
    }