在F#中有什么方法可以获取传递给函数的变量的名称吗?
例:
let velocity = 5
let fn v = v.ParentName
let name = fn velocity // this would return "velocity" as a string
Run Code Online (Sandbox Code Playgroud)
先感谢您
编辑:
为什么这段代码不起作用?它匹配为值,因此我无法检索"变量"名称.
type Test() =
let getName (e:Quotations.Expr) =
match e with
| Quotations.Patterns.PropertyGet (_, pi, _) -> pi.Name + " property"
| Quotations.Patterns.Value(a) -> failwith "Value matched"
| _ -> failwith "other matched"
member x.plot v = v |> getName |> printfn "%s"
let o = new Test()
let display () =
let variable …
Run Code Online (Sandbox Code Playgroud) 我过去常常只使用p
和span
元素...但我总是推动使用正确的元素,这是我之前没有考虑过的推荐书.
这就是我的想法......
<div class="testimonial">
<blockquote>I love your products!</blockquote>
<span>Jim Testimonial-giver</span>
</div>
Run Code Online (Sandbox Code Playgroud)
这看起来是最好的方法吗?有最好的做法吗?
<blockquote>
<p>
<a id="aptest" name="aptest">Applied Testin.....</a>
<br />
<span class="QuoteAttr">-- Shane P. M...</span>
</p>
</blockquote>
Run Code Online (Sandbox Code Playgroud)
我应该复制一下W3C是如何做到的,毕竟不应该是正确的吗?
引用时
<@ 1 + 1 @>
Run Code Online (Sandbox Code Playgroud)
我想要"1 + 1"
代替
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
在C#中,我可以使用表达式树很容易地创建对象图的字符串表示.
public static string GetGraph<TModel, T>(TModel model, Expression<Func<TModel, T>> action) where TModel : class
{
var method = action.Body as MethodCallExpression;
var body = method != null ? method.Object != null ? method.Object as MemberExpression : method.Arguments.Any() ? method.Arguments.First() as MemberExpression : null : action.Body as MemberExpression;
if (body != null)
{
string graph = GetObjectGraph(body, typeof(TModel))
return graph;
}
throw new Exception("Could not create object graph");
}
Run Code Online (Sandbox Code Playgroud)
在F#中我一直在看引文试图做同样的事情,并且无法弄明白.我曾尝试使用PowerPack库将引用转换为Expression,但到目前为止还没有运气,而且互联网上的信息在这个主题上看起来相当稀少.
如果输入是:
let result = getGraph myObject <@ myObject.MyProperty @>
Run Code Online (Sandbox Code Playgroud)
输出应为"myobject.MyProperty"
[<ReflectedDefinition>]
let rec x = (fun() -> x + "abc") ()
Run Code Online (Sandbox Code Playgroud)
上面带有递归值的示例代码会产生以下F#编译器错误:
错误FS0432:[<ReflectedDefinition>]术语不能包含前缀拼接运算符'%'的使用
我在上面的代码中看不到任何切片操作符用法,看起来像一个bug ... :)
看起来这只是报价的问题ReflectedDefinitionAttribute
,正常报价效果很好:
let quotation =
<@ let rec x = (fun() -> x + "abc") () in x @>
Run Code Online (Sandbox Code Playgroud)
通过隐藏Lazy.create
和Lazy.force
使用产生预期结果:
val quotation : Quotations.Expr<string> =
LetRecursive
([(x, Lambda (unitVar,
Application
(Lambda (unitVar0,
Call (None,
String op_Addition[String,String,String](String, String),
[Call (None,
String Force[String](Lazy`1[System.String]), // `
[x]), Value ("abc")])),
Value (<null>)))),
(x, Call (None, Lazy`1[String] Create[String](FSharpFunc`2[Unit,String]), [x])),
(x, Call (None, String Force[String](Lazy`1[String]), …
Run Code Online (Sandbox Code Playgroud) 我继续为F#引用的表达式打印机,它不一定是完美的,但我想看看有什么可能.该有源图案中Microsoft.FSharp.Quotations.Patterns
和Microsoft.FSharp.Quotations.DerivedPatterns
用于分解引述表达式将通常提供MemberInfo
在适当的时候情况下,这些可以被用来获得一个属性,功能等和它们的"声明"类型的名称,诸如模块或静态类.问题是,我只知道如何CompiledName
从这些实例中获取,但我喜欢F#名称.例如,
> <@ List.mapi (fun i j -> i+j) [1;2;3] @> |> (function Call(_,mi,_) -> mi.DeclaringType.Name, mi.Name);;
val it : string * string = ("ListModule", "MapIndexed")
Run Code Online (Sandbox Code Playgroud)
如何重写这个匹配才能返回("List", "mapi")
?可能吗?
仅供参考,这是Stringer Bell和pblasucci帮助的最终解决方案:
let moduleSourceName (declaringType:Type) =
FSharpEntity.FromType(declaringType).DisplayName
let methodSourceName (mi:MemberInfo) =
mi.GetCustomAttributes(true)
|> Array.tryPick
(function
| :? CompilationSourceNameAttribute as csna -> Some(csna)
| _ -> None)
|> (function | Some(csna) -> csna.SourceName | None -> mi.Name)
//usage:
let sourceNames =
<@ List.mapi …
Run Code Online (Sandbox Code Playgroud) 我以为我可以用引号做到这一点 - 但我看不出怎么做.
我应该只使用一个功能表和他们的名字 - 或者他们是这样做的一种方式?
谢谢.
欲了解更多信息......
我从excel调用了很多f#函数,我想知道我是否可以编写af#函数
让fs_wrapper(f_name:string)(f_params:list double)=这个位用f_params调用fname
然后使用
= fs_wrapper("my_func",3.14,2.71)
在工作表中而不是分别包装所有功能.
它在F#社区的PowerPack中的报价编制工厂的常识产生很慢的代码,其实这么慢,它的性能比幼稚的解释更是雪上加霜。我一直在寻找造成这种情况的原因,但到目前为止我还没有找到令人信服的答案。有人声称,发生这种情况的原因要么是引用中模式匹配等内容的低效表示,要么是该库使用的表达式树固有的低效率。我想用一个简单的例子来说明为什么我认为这两者都不是真的:
#r "FSharp.Powerpack.Linq.dll"
open System
open System.Linq.Expressions
open Microsoft.FSharp.Quotations.Patterns
let powerpack = Microsoft.FSharp.Linq.QuotationEvaluator.Compile <@ 1 + 1 @>
// explicitly rewrite above quotation with expression trees
let expressionTree =
let (Call(_,addM,_)) = <@ 1 + 1 @>
let constExpr (x : 'T) = Expression.Constant(box x, typeof<'T>)
let eval = Expression.Call(addM, constExpr 1, constExpr 1)
let lambda = Expression.Lambda<Func<int>>(eval)
lambda.Compile()
// reflection - based evaluation
let reflection =
let (Call(_,addM,_)) = <@ 1 + 1 @>
fun () -> …
Run Code Online (Sandbox Code Playgroud) 换句话说,我怎么知道使用哪一个?
我知道当我使用琴弦时,我会这样做
string = "This is a string"
Run Code Online (Sandbox Code Playgroud)
我何时会使用''或""""""?
这是访问F#中的动态对象的另一种方法.我正在使用它let y = x.Where(fun x -> x.City ="London").Select("new(City,Zip)")
来参数化查询并提取必要的项目.这些对应于SQL查询中的列,并由datacontext的属性表示.这是我想作为参数传递的部分.
type Northwind = ODataService<"http://services.odata.org/Northwind/Northwind.svc">
let db = Northwind.GetDataContext()
let query2 = query { for customer in db.Customers do
select customer} |> Seq.toArray
let qryfun (x:Northwind.ServiceTypes.Customer) =
query { for x in query2 do
select (x.City,x.CompanyName,x.Country)}
Run Code Online (Sandbox Code Playgroud)
基本上我不仅要传递,x
而且还要传递x.*
.当我访问一个已修复的数据库时,我可以将x分解出来.但是我现在有40个小函数提取不同的列.是否有可能将其分解为一个函数并将该属性作为参数传递?所以有时我会提取x.City
但其他时间x.Country
.我尝试过使用引文,但不能正确拼接,也许这不是正确的方法.
quotations ×10
f# ×8
function ×1
linq ×1
markup ×1
parameters ×1
python ×1
python-3.x ×1
recursion ×1
reflection ×1
syntax ×1
xhtml ×1