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
Reflection 在编译时检查代码引用结构_Reflection_F# - Fatal编程技术网

Reflection 在编译时检查代码引用结构

Reflection 在编译时检查代码引用结构,reflection,f#,Reflection,F#,我是否可以定义一个引号表达式参数,以便不仅在编译时检查表达式的结果类型 还有调用站点表达式 让我们看一个例子: type A = { a : int } type Checker () = static member Check(e : Expr<int>) : ResultType = ... 下面也汇编了 Checker.Check <@ getInt a @> Checker.Check 但是,如何防止第二个示例编译并只允许Property

我是否可以定义一个引号表达式参数,以便不仅在编译时检查表达式的结果类型 还有调用站点表达式

让我们看一个例子:

type A = {
    a : int
}

type Checker () =
     static member Check(e : Expr<int>) : ResultType = ...
下面也汇编了

Checker.Check <@ getInt a @>
Checker.Check
但是,如何防止第二个示例编译并只允许
PropertyGet
s?(仅作为示例)。

我知道我可以在运行时检查表达式的结构,但我喜欢在编译时进行检查。

正如Fyodor在一篇评论中所说,无法确保引用在编译时只具有特定的形状。这是非常不幸的,但所有基于引号(或基于表达式树)的库都会遇到这种情况(最明显的是LINQ),如果您的需求是“仅属性getter”,那么我想您可以将其作为运行时检查

如果我真的想保证这一点,我可能会尝试使用,这让你得到。然后,您可以遍历树,找到项目中的所有引用,并报告错误(可以作为linter插件以某种可扩展的方式完成,其他人也可以从中受益)


如果你使用DSL,那么你可以写,比如说,
a |>get“foo”|>get“bar”
(使用管道),或者
a?foo?bar
(使用
操作符),但是你无法检查名称,这似乎比无法检查引号的正确形状更糟糕。

你不能。如果这是一个关键要求,我建议使用组合符库而不是引用。这会有什么帮助?您可以使您的组合符(或者,更确切地说,它们生成的数据类型)不允许创建无效数据。你知道,“使无效数据不可再现”等等。嗯,不确定组合器是否有那么大的帮助。例如,我可以定义
静态成员检查(c:SomeCombinatorint>)=…
,但如果我这样设置它,真的会有帮助吗
Checker.Check(SomeCombinator(趣味a->99))
。诚然,它比简单地检查结果类型要好,但只是稍微好一点,所以非类型化的变体肯定没有出路;-)但是,我不确定编译器服务和类型化表达式树会有什么帮助。至少,如果我们是在正常的工作流程中讨论,而不是在两次编译中。你能勾勒出你的设想吗?@robkuz你肯定需要像两遍编译这样的东西。但是您可以将其作为FSharpLint()中的一个集成,并将其作为VS插件,这将使体验更加美好。
let getInt (a:A) : int = a.a
Checker.Check <@ getInt a @>