问题标签 [computation-expression]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
446 浏览

f# - 计算表达式不执行 Let

我正在使用 F# v 1.9.6.2,并且我定义了一个非常简单的计算表达式:

我在代码中添加了一些打印语句来告诉我在计算表达式中调用了哪些方法。当我执行以下语句时:

我希望控制台打印出以下内容:

但我的实际结果如下:

换句话说,F# 似乎没有执行该Let成员。当我重新编写Let抛出异常时,代码运行时没有异常。此外,当我完全注释掉该Let成员时,我没有收到一条错误消息说明The field, constructor or member 'Let' is not defined,并且代码按预期执行。

(我尝试使用 Reflector 调查代码,但通常情况下,反编译的 F# 被破坏,超出了可读性。)

看起来计算表达式的规范已经改变。let绑定不再被视为语法糖,计算Let工作流程中不再需要成员吗?

0 投票
2 回答
963 浏览

f# - 为什么这个 F# 计算表达式会给出警告?

这段代码:

打印成功“是!”

但是给出一个警告,暗示它不应该工作:

File1.fs(19,3):警告 FS0708:仅当计算表达式构建器定义了“ReturnFrom”方法时,才可以使用此控制构造

似乎是一个奇怪的警告:如果它是正确的,那么代码不应该工作。真的只是说builder必须合成ReturnFrom吗?

(F# 版本 1.9.7.4,为 .NET Framework 版本 v4.0.21006 编译)

0 投票
2 回答
1010 浏览

f# - F# 中的自定义计算表达式

我一直在玩 F#(又名计算表达式)中的 monad,我写了这个简单的 Identity monad:

我不明白我在标记行中遇到的错误:

此表达式应具有类型 Identity<'a> 但此处具有类型 'b * 'c

我认为这没有意义,因为 getInt() 显然是 type 的值Identity<'a>

谁能告诉我我做错了什么?

0 投票
2 回答
769 浏览

f# - 如何创建支持单步执行等功能的 F# 工作流?

我想创建一个构建器来构建表达式,该表达式在每个步骤之后返回类似于延续的东西。

像这样的东西:

'let a' 行返回包含稍后要评估的其余表达式的内容。

为每个步骤数使用单独的类型很简单,但当然不是特别有用:

结果就是我要找的:

但我无法弄清楚这种情况的一般情况是什么。

我想要的是能够将事件输入到这个工作流中,所以你可以编写如下内容:

并让事件触发工作流程中的下一步。(特别是,我想在 MonoTouch 中玩这种东西 - iPhone 上的 F#。传递 objc 选择器让我发疯。)

0 投票
4 回答
1154 浏览

c# - 对 IEnumerable 以外的类型(monad?)进行操作的 LINQ 查询表达式-- 可能的用途?

我正在阅读Tomas Petricek 和 Jon Skeet所著的Real-world functional programming一书,我很难消化关于计算表达式1)(又名 monads)的部分。

通过这本书,我了解到——与我以前的经验相反——LINQ 查询表达式不限于IEnumerable<T>,而是也可以在其他自定义类型上工作。这对我来说似乎很有趣,我想知道是否存在查询表达式语法 ( from x in ... select ...) 非常适合的场景。


一些背景资料:

显然,这种自定义类型被称为计算类型,它们被描述为与Haskell中的monad基本相同。我一直无法理解 monad 到底是什么,但根据书中的说法,它们是通过两个称为bindreturn的操作来定义的。

在函数式编程中,这两个操作的类型签名将是(我认为):

M一元类型的名称在哪里。

在 C# 中,这对应于:

事实证明,LINQ Enumerable.Select(投影运算符)与绑定操作具有完全相同的签名M := IEnumerable

我的自定义 LINQ 计算类型:

使用这些知识,我现在可以编写一个自定义计算类型,它不是 IEnumerable

现在我可以Wrapped<T>在 LINQ 查询表达式中使用,例如:

当然,这个例子不是很有用,但它演示了如何使查询表达式做一些除了使用集合之外的事情,例如用某种类型包装和展开值。


问题:

上面的计算类型似乎不是很有用。因此我想知道,使用 LINQ 查询表达式还有哪些其他合理的用途(除了处理集合)?


1)第 12.4 节:“介绍替代工作流程”,从第 334 页开始。

0 投票
2 回答
626 浏览

f# - 计算表达式中的递归函数

先来点背景。我目前正在学习一些关于单子解析器组合器的东西。当我尝试从本文(第 16-17 页)转移“chainl1”函数时,我想出了这个解决方案:

我用一些大的输入测试了这个函数,得到了一个 StackOverflowException。现在我想知道,是否可以重写一个递归函数,它使用一些计算表达式,以某种方式使用尾递归?

当我扩展计算表达式时,我看不出它通常是如何实现的。

0 投票
1 回答
513 浏览

f# - 递归计算表达式

上一个问题中,我被告知如何重写我的计算表达式,以便它使用尾递归。我重写了我的代码,但仍然得到了 StackOverflowException。为了找到问题,我使用 state monad 编写了一些小代码(取自此博客条目):

这再次抛出 StackOverflowException,尽管 Loop 函数可以使用尾递归(?)。我猜 StateBuilder 类有问题。我试图用延迟方法做一些事情。将所有内容包装在一个额外的 lambda 中,但没有成功。我现在完全卡住了。这是我的第二次尝试(不编译):

0 投票
2 回答
1151 浏览

c# - 如何将 `where T : U` 泛型类型参数约束从 C# 转换为 F#?

F# 的类型推断规则给我带来了一些麻烦。我正在编写一个简单的计算构建器,但无法正确获取我的泛型类型变量约束。


我想要的代码在C#中如下所示:


到目前为止,我为F# 版本提出的最好的(但非编译代码)是:

不幸的是,我不知道如何翻译该方法的where TA : TZ类型约束Bind。我认为它应该是类似′a when ′a :> ′z的,但 F# 编译器在任何地方都不喜欢这样,我总是以一些泛型类型变量约束到另一个。

有人可以告诉我正确的 F# 代码吗?


背景:我的目标是能够编写这样的 F# 自定义工作流:

0 投票
1 回答
249 浏览

f# - 计算工作流的问题

尝试遵循专家 f# 书中的示例,并且工作流有问题...代码如下:

问题是,当所有值都为真时,我按预期得到一个 Some(true, true, true),但如果传入的值之一为假,则 foo 为空(!)。有人ftw吗?

谢谢!

0 投票
1 回答
202 浏览

f# - 如何最好地抓住失踪让!,做!,返回和返回!在 F# 的计算表达式中

我喜欢计算表达式,但我会犯一些简单的错误,比如忘记 return 关键字或 ! 关于 let! 然后返回!,或者我只是忘记写do!。状态单子经常发生这种情况,我倾向于忘记状态,只关注我定义的单子运算符。

我有时会确保我的单子运算符返回一个“单子类型”而不是“匿名”函数的类型。这有助于跟踪我健忘的打字,但并不是很理想。有人有更好的技巧吗?