我对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()?我是不是想以错误的方式解决我的问题?
由于
答案 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
module,here's iter