- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是一名学生,想学习F#和函数式编程逻辑,但我对计算表达式有疑问。我认为我无法理解计算表达式的逻辑,因为我无法解决这个问题,并且我没有看到在这个问题中使用计算表达式有任何有用的东西。我认为这是一种重写 F# 的几个基本功能并以我们自己的方式实现的方法,但在这个问题中我看不到要点。感谢您抽出宝贵的时间,很抱歉提出了很长的问题。
A function from a type 'env to a type 'a can be seen as a computation that
computes a value of type 'a based on an environment of type 'env. We call such
a computation a reader computation, since compared to ordinary computations,
it can read the given environment. Below you find the following:
• the definition of a builder that lets you express reader computations
using computation expressions
• the definition of a reader computation ask : 'env -> 'env that returns the
environment
• the definition of a function runReader : ('env -> 'a) -> 'env -> 'a that
runs a reader computation on a given environment
• the definition of a type Expr of arithmetic expressions
Implement a function eval : Expr -> Map<string, int> -> int that evaluates
an expression using an environment which maps identifiers to values.
NB! Use computation expressions for reader computations in your implementation.
Note that partially applying eval to just an expression will yield a function of
type map <string, int> -> int, which can be considered a reader computation.
This observation is the key to using computation expressions.
The expressions are a simplified subset based on
Section 18.2.1 of the F# 4.1 specification:
https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf
*)
type ReaderBuilder () =
member this.Bind (reader, f) = fun env -> f (reader env) env
member this.Return x = fun _ -> x
let reader = new ReaderBuilder ()
let ask = id
let runReader = (<|)
type Expr =
| Const of int // constant
| Ident of string // identifier
| Neg of Expr // unary negation, e.g. -1
| Sum of Expr * Expr // sum
| Diff of Expr * Expr // difference
| Prod of Expr * Expr // product
| Div of Expr * Expr // division
| DivRem of Expr * Expr // division remainder as in 1 % 2 = 1
| Let of string * Expr * Expr // let expression, the string is the identifier.
let eval (e:Expr) : (Map<string, int> -> int) = failwith "not yet implemented"
// //Example:
// //keeping in mind the expression: let a = 5 in (a + 1) * 6
// let expr = Let ("a",Const 5, Prod(Sum(Ident("a"),Const 1),Const 6))
// eval expr Map.empty<string,int>
// should return 36
`
最佳答案
读取器计算表达式将允许您通过多个计算隐式地对环境进行线程化。例如,您可能有类似的内容:
let rec eval e : Map<string,int> -> int =
reader {
match e with
...
| Add(e1, e2) ->
let! i1 = eval e1 // implicitly thread environment through
let! i2 = eval e2 // same here
return i1 + i2
...
}
尽管eval
的完整签名是Expr -> Map<string,int> -> int
,当我们使用let!
时在计算表达式中我们只需要传递 Expr
中,我们可以将结果绑定(bind)到 int
无需显式传递 map 。
请注意,对于 Ident
和Let
在这种情况下,您实际上需要显式处理映射来查找或设置标识符的值 - 但您可以使用 let! m = ask
将 map 从环境中拉出。
当然完全有可能编写 eval
的实现不使用 reader
表达式,但您可能会发现在任何地方对环境进行线程化只会给代码增加乏味的噪音,使其更难以理解。
关于F# 计算表达式的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53659986/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
我有实体: @Entity @Table(name = "CARDS") public class Card { @ManyToOne @JoinColumn(name = "PERSON_I
我正在尝试计算二维多边形的表面法线。我正在使用 OpenGL wiki 中的 Newell 方法来计算表面法线。 https://www.opengl.org/wiki/Calculating_a_S
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 7 年前。 Improve
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我这里有以下 XML: Visa, Mastercard, , , , 0, Discover, American Express siteonly, Buyer Pay
即将发生的 Google 政策变更迫使我们实现一个对话框,以通知欧盟用户有关 Cookie/设备标识符用于广告和分析的情况。我只想向欧盟用户显示此对话框。我不想使用额外的权限(例如 android.p
本文分享自华为云社区《华为大咖说 | 企业应用AI大模型的“道、法、术” ——道:认知篇》,作者:华为云PaaS服务小智。 本期核心观点 上车:AGI是未来5~10年内,每个人都无法回避的技
我有一个与酒精相关的网站,需要先验证年龄,然后才能让他们进入该网站。我使用 HttpModule 来执行此操作,该模块检查 cookie,如果未设置,我会将它们重定向到验证页面。我验证他们的年龄并存储
在欧盟,我们有一项法律,要求网页请求存储 cookie 的许可。我们大多数人都了解 cookie 并同意它们,但仍然被迫在任何地方明确接受它们。所以我计划编写这个附加组件(ff & chrome),它
以下在 C 和/或 C++ 中是否合法? void fn(); inline void fn() { /*Do something here*/ } 让我担心的是,第一个声明看起来暗示函数将被定义
我是一名优秀的程序员,十分优秀!