F# 绑定中f的gettings属性
我在工作流中有一些代码,我想在其中获取函数的属性 表达方式是这样的F# 绑定中f的gettings属性,f#,computation-expression,F#,Computation Expression,我在工作流中有一些代码,我想在其中获取函数的属性 表达方式是这样的 let! accounts = _accounts() 在我的约束下,我有这个 member this.Bind(x,f) = let attributes = f.GetType() .GetCustomAttributes(typeof<myattribute>,false) 成员this.Bind(x,f)= 让属性= f、 GetType() .GetCustomAt
let! accounts = _accounts()
在我的约束下,我有这个
member this.Bind(x,f) =
let attributes =
f.GetType()
.GetCustomAttributes(typeof<myattribute>,false)
成员this.Bind(x,f)=
让属性=
f、 GetType()
.GetCustomAttributes(typeof,false)
其思想是获取函数_accounts()的属性。然而,f代表的是计数,而不是_账户,因此无论如何,我可以得到被调用函数的属性?我要后退一步-首先,你需要弄清楚你想要建模的计算是什么。根据您所说的,您可以保留一个包含一些审核日志信息的结果:
type Audited<'T> =
{ Log : string list
Result : 'T }
如果您的
accounts
函数返回正确的Audited,您就可以使用它了。我会后退一步,首先,您需要弄清楚您要建模的计算是什么。根据您所说的,您可以保留一个包含一些审核日志信息的结果:
type Audited<'T> =
{ Log : string list
Result : 'T }
如果accounts
函数返回正确的audited,您可以将f
视为工作流的其余部分,因此很难将其删除(它将根据您的其余代码进行更改)你想用这个做什么?是的,你的右f当然是延续,我可能不太难,但我被卡住了:)@Carsten我想从一个被调用的函数中获取信息,用于审计目的。从本质上说,我想我是在试图解决使用计算表达式的一个交叉问题。现在,除了引号/反射之外,我什么都做不到,这很糟糕——不确定你的目标是什么,但有时你可以使用类型/泛型来标记信息——例如,不使用你可以标记的属性带有type Taged=Taged of'value
的信息-在这里,您可以使用'tag
类型来获取与度量单位非常类似的附加信息-就像一个想法一样,您可以将f
视为工作流的其余部分-因此很难从中获取此信息(它将根据您的其余代码进行更改)你想用这个做什么?是的,你的右f当然是延续,我可能不太难,但我被卡住了:)@Carsten我想从一个被调用的函数中获取信息,用于审计目的。从本质上说,我想我是在试图解决使用计算表达式的一个交叉问题。现在,除了引号/反射之外,我什么都做不到,这很糟糕——不确定你的目标是什么,但有时你可以使用类型/泛型来标记信息——例如,不使用你可以标记的属性带有type Taged=Taged of'value
的信息-在这里,您可以使用'tag
类型获取与度量单位非常类似的附加信息-就像一个理想最终将我置于一个可以继续操作的位置一样。简单版本将不起作用,因为函数的元数据决定了审核将如何进行。该功能将标记有关于审计的各种信息。法律可能会要求我们跟踪调用该函数的人,而在其他情况下,可能会有其他要求,并且根据审计要求和用户的组合,流程可能会失败。简言之,(可能)元数据会影响计算流。这肯定会让我处于可以继续的位置。简单版本将不起作用,因为函数的元数据决定了审核将如何进行。该功能将标记有关于审计的各种信息。法律可能会要求我们跟踪调用该函数的人,而在其他情况下,可能会有其他要求,并且根据审计要求和用户的组合,流程可能会失败。简而言之,(可能)元数据会影响计算流。
let accounts () =
{ Result = 40
Log = ["accounts"] }
let stocks () =
{ Result = 2
Log = ["stocks"] }
audit {
let! a = accounts()
let! s = stocks()
return a + s }
let plain () = 123
open Microsoft.FSharp.Quotations
type AuditBuilder with
member x.Bind(e:Expr<'T>, f:'T -> _) =
match e with
| Patterns.Call(None, mi, []) ->
let r = f (mi.Invoke(null, [| |]) :?> 'T)
{ r with Log = r.Log @ [mi.Name] }
| _ -> failwith "invalid"
audit {
let! p = <@ plain() @>
return p }