从f#中的函数引用/别名执行函数

时间:2014-09-30 14:35:16

标签: function reference f#

我对F#和函数式编程仍然很陌生,所以考虑到这一点......

我想编写一个通信处理程序,它从CAN总线读取数据,并根据ID执行不同的功能(或具有不同行为的相同功能)。我知道我可以编写一个类似C开关语句的函数(I.E.匹配...)但我希望处理程序更通用(数据驱动),所以我可以重用它。

我认为在创建处理程序时我会传入Map(或其他一些有用的数据结构)。如果可以的话,我也会尝试使用所有不可变类型(不是我的常规思维方式)。

我编写了一些不能编译的简单测试代码,在尝试了不同的方式和大量的网络搜索后,我仍然无法弄明白。这让我想知道我是否会以完全错误的方式解决这个问题。

简单的测试代码:

let one() = printfn "One"
let two() = printfn "Two"

let callbacks =
    [ ( 1, one );
      ( 2, two )
    |> Map.ofList

let f = callbacks.TryFind(1)
f()

它不喜欢f()。说这不是一个功能。如果我改写

let f() = callbacks.TryFind(1)

它仍然不喜欢它。

我如何调用f()?我是不是想以错误的方式解决我的问题?

由于

1 个答案:

答案 0 :(得分:3)

会员TryFind以及Map.tryFind函数返回Option<V>

let f = callbacks.TryFind(1);;

val f : (unit -> unit) option = Some <fun:callbacks@4>

这意味着您无法调用该函数,您必须处理在地图中找不到密钥且没有匹配值的情况。它可以通过模式匹配来完成:

let r = match f with
        | Some(fn) -> fn()
        | None -> // what now? You can just return unit
                  ()

或通过组合器达到同样的效果:

callbacks |> Map.tryFind(1) |> Option.iter(fun f -> f());;
One
val it : unit = ()

如果在这种情况下找不到密钥,您可能会注意到没有任何反应:

callbacks |> Map.tryFind(5) |> Option.iter(fun f -> f());;
val it : unit = ()

行为全部记录在Core.Option modulehere's iter