对于无法使用静态类型系统表达某些功能的情况,我正在尝试探索 F# 的动态功能。因此,我正在尝试mapN为(比如说)Option类型创建一个函数,但是我在创建一个具有动态参数数量的函数时遇到了麻烦。我试过了:
let mapN<'output> (f : obj) args =
let rec mapN' (state:obj) (args' : (obj option) list) =
match args' with
| Some x :: xs -> mapN' ((state :?> obj -> obj) x) xs
| None _ :: _ -> None
| [] -> state :?> 'output option
mapN' f args
let toObjOption (x : #obj option) =
Option.map (fun x -> x :> obj) x
let a = Some 5
let b = Some "hi"
let c = Some true
let ans = mapN<string> (fun x y z -> sprintf "%i %s %A" x y z) [a |> toObjOption; b |> toObjOption; c |> toObjOption]
Run Code Online (Sandbox Code Playgroud)
(它接受传入的函数并一次应用一个参数)它编译,但在运行时我得到以下信息:
System.InvalidCastException: Unable to cast object of type 'ans@47' to type
'Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]'.
Run Code Online (Sandbox Code Playgroud)
我意识到为选项创建计算表达式或map2通过map5左右定义会更惯用,但我特别想探索 F# 的动态功能,看看这样的事情是否可行。
这只是一个不能在 F# 中完成的概念,还是我缺少一种方法?
我认为你只能通过反思来采取这种方法。
但是,还有其他方法可以解决整个问题,而无需动态处理或使用您提到的其他静态选项。您可以使用 获得很多相同的便利Option.apply,您需要自己定义(或从库中获取)。这段代码是从F# 中窃取和改编的,目的是为了好玩和获利:
module Option =
let apply fOpt xOpt =
match fOpt,xOpt with
| Some f, Some x -> Some (f x)
| _ -> None
let resultOption =
let (<*>) = Option.apply
Some (fun x y z -> sprintf "%i %s %A" x y z)
<*> Some 5
<*> Some "hi"
<*> Some true
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
603 次 |
| 最近记录: |