我开始学习F#了.我非常精通C#等编程语言(并且通常使用.NET框架),但函数式编程对我来说是新的.我学得最好的方法是写一本关于这个主题的书并开始阅读 - 所以我抓了一份"专家F#"和"F#科学家".有几次我得到的印象是,由于最近语言的变化,这些书似乎已经过时了 - 没什么太戏剧性的,但它给人一种唠叨的感觉,可能会有更多.
现在F#2.0似乎已经稳定下来,看看"真正的"F#与那些(和类似的)书中所描述的语言版本相比如何变得很好.
所以我的问题是:
编辑: 谢谢大家的答案!
就发行说明而言,我能够在Don Syme的博客上挖掘以下"详细发布说明"帖子,适用于1.9.2之后的F#版本(版本"专家F#"提到的是在书):
我没有找到关于1.9.5版本的任何内容 - 那个曾经存在过吗?
使用Azure功能的绑定选项,可以根据从触发器派生的参数(例如,触发该功能的队列消息)指定要写入的Blob的名称; 文档显示了一个例子.
我的问题是:处理blob名称事先不知道的情况的最佳方法是什么,但实际上是作为函数执行的一部分计算的?
并且相关:如果函数可能会或可能不会产生输出blob(或多个输出blob!),根据其计算结果怎么办?
据我所知,Azure Function的绑定机制在这些情况下没有多大帮助,最简单的方法是引用一个用azure blob编写"经典方式"的程序集.但是有更惯用的方式吗?
我注意到,当您尝试编译时,以下代码会出错:
let xx =
seq {
let! i = [ 1; 2 ]
let! j = [ 3; 4 ]
yield (i,j)
}
Run Code Online (Sandbox Code Playgroud)
这给出的错误是" 错误FS0795:不再允许在序列表达式中使用'let!x = coll'.而是使用'for x in coll'. "这条消息当然是清楚的,并演示了如何解决它; 固定代码是:
let xx =
seq {
for i in [ 1; 2 ] do
for j in [ 3; 4 ] do
yield (i,j)
}
Run Code Online (Sandbox Code Playgroud)
我的问题不是如何解决这个问题,而是为什么"让!" 首先不允许在序列表达式中?我可以看到让我们这样的事实!迭代表达式可能会让一些人感到意外,但这不足以禁止构造.我也看到"for"在这里是如何更强大的,因为"let!"的版本 在迭代范围内烘焙为"直到序列表达式结束".
但是,能够迭代序列而不必缩进代码正是我所寻找的(用于遍历树结构).我假设要获得这个语义,我将不得不创建一个新的表达式构建器,其行为主要类似于"seq"表达式构建器,但允许"let!" 迭代,不是吗?
根据Brian的评论添加,为我的潜在问题提供解决方案:
我没有意识到for block中的缩进是不需要的,第二个样本可以重写为:
let xx =
seq {
for i in [ 1; 2 ] do
for j …Run Code Online (Sandbox Code Playgroud) 通过“诊断日志”配置部分中的配置,Azure Web应用程序以及扩展的“ Azure功能”允许将日志消息发送到Blob存储。
但是,传递给C#函数(v2)实现的默认ILogger实例将忽略该设置。相反,似乎您需要手动构建一个记录器才能使用此功能,如下所示。请注意,您需要Microsoft.Extensions.Logging.AzureAppServices从NuGet 添加以进行编译。
[FunctionName("myfun")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req,
ILogger log)
{
log.LogInformation("This does not end up in the app log.");
var factory = new LoggerFactory().AddAzureWebAppDiagnostics();
var log2 = factory.CreateLogger("MyFun");
log2.LogInformation("This *does* end up in the app log, if configured.");
log2.LogError("Fake error for testing logging functionality (2)");
}
Run Code Online (Sandbox Code Playgroud)
我的问题:有没有更优雅的方法来获取记录器,该记录器写入已配置的App Log Blob存储?我希望log传递给该函数的功能已经具有此功能(可能是通过观察已配置的应用程序日志触发的),但是默认情况下它没有,并且我看不到如何添加的清晰路径,既不能通过配置,也不能通过ILogger log其他方式替换参数。
是否可以在ASP.NET Web API路由配置中添加允许处理看起来有点像文件名的URL的路由?
我尝试添加以下条目WebApiConfig.Register(),但这不起作用(使用URI api/foo/0de7ebfa-3a55-456a-bfb9-b658165df5f8/bar.group.json):
config.Routes.MapHttpRoute(
name: "ContextGroupFile",
routeTemplate: "api/foo/{id}/{filetag}.group.json",
defaults: new { controller = "foo", action = "getgroup"}
);
Run Code Online (Sandbox Code Playgroud)
以下确实有效(FooController.GetGroup(id,filetag)按预期调用)(使用URI api/foo/0de7ebfa-3a55-456a-bfb9-b658165df5f8/group/bar):
config.Routes.MapHttpRoute(
name: "ContextGroupFile",
routeTemplate: "api/foo/{id}/group/{filetag}",
defaults: new { controller = "foo", action = "getgroup"}
);
Run Code Online (Sandbox Code Playgroud)
失败的情况会返回一个IIS错误(404 - 找不到文件),看起来它是由我的应用程序之外的东西创建的.错误页面(由IIS Express生成)包含以下错误详细信息:
Module = IIS Web Core
Notification = MapRequestHandler
Handler = StaticFile
Error Code = 0x80070002
Run Code Online (Sandbox Code Playgroud)
我想这意味着一个名为"StaticFile Handler"的东西在它到达我的代码之前就已经得到了请求.最大的问题是:有没有办法防止这种情况发生?
我想知道C#(或底层的.NET框架)是否支持某种"泛型委托实例":这是一个委托实例仍然有一个未解析的类型参数,在调用委托时要解析(当时不是代表已创建).我怀疑这是不可能的,但无论如何我都在问它......
这是我想要做的一个例子,有一些"???" 插入C#语法似乎无法满足我想要的地方.(显然这段代码不能编译)
class Foo {
public T Factory<T>(string name) {
// implementation omitted
}
}
class Test {
public void TestMethod()
{
Foo foo = new Foo();
??? magic = foo.Factory; // No type argument given here yet to Factory!
// What would the '???' be here (other than 'var' :) )?
string aString = magic<string>("name 1"); // type provided on call
int anInt = magic<int>("name 2"); // another type provided on another call
// Note the underlying calls …Run Code Online (Sandbox Code Playgroud)