我是一个想学习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
`