[英]How to write a arithmetic expression using a discriminated union in F#?
Recently, I started learning F# and I am a bit struggling with discriminated unions and function signatures. 最近,我开始学习F#,我对有区别的工会和功能签名有点挣扎。
I am trying to define an arithmetic expression (for sum, product, multiply, average etc) as a discriminate union and write a function that evaluates it. 我试图将一个算术表达式(求和,乘积,乘法,平均等)定义为一个判别联合并编写一个计算它的函数。 However, I can't figure out what I am doing wrong.
但是,我无法弄清楚我做错了什么。 Could anyone point me in the right direction?
有人能指出我正确的方向吗? This what I've tried so far:
这是我到目前为止所尝试的:
type Expr =
| Sum of int * int
| Avg of int * int
| Mul of int * int
let Evaluate (input : Expr) =
match input with
| Sum(a,b) -> a + b
printfn "%A" (Sum(5,10))
My output is : 我的输出是:
Sum (5,10)
I also tried something like : 我也试过类似的东西:
type Expr = int -> int -> int
let evaluate (a : Expr) (b : Expr) =
match a,b with
| a,b -> (fun a -> a + b)
printfn "%A" (evaluate 5 10)
since all common arithmetic expressions (like sum, product, multiply, average etc) take two integer inputs and output a single integer. 因为所有常见的算术表达式(如sum,product,multiply,average等)都需要两个整数输入并输出一个整数。
I am getting errors for: 'This expression was expected to have type Expr but here has type Int'. 我收到错误:'这个表达式预计有类型Expr但这里有类型Int'。
let evaluate (input : Expr) =
match input with
| Sum(a,b) -> a + b
| Avg(a,b) -> a + b / 2
| Mul(a,b) -> a * b
let evaluate = function
| Sum(a,b) -> a + b
| Avg(a,b) -> a + b / 2
| Mul(a,b) -> a * b
Attempt 1 looks about right but limited as it doesn't allow you to create expressions like 1+2+3
. 尝试1看起来正确但有限,因为它不允许您创建像
1+2+3
这样的表达式。
Instead you could try something like this: 相反,你可以尝试这样的事情:
type Expr =
| Constant of int
| Add of Expr*Expr
| Sub of Expr*Expr
| Mul of Expr*Expr
| Div of Expr*Expr
A bit more flexible and with support for bindings like x
, y
and so on: 更灵活,支持
x
, y
等绑定:
type Expr =
| Constant of int
| Binding of string
| BinaryOp of string*(int -> int -> int)*Expr*Expr
| UnaryOp of string*(int -> int)*Expr
Your first attempt comes close. 你的第一次尝试接近了。
type Expr =
| Sum of int * int
| Avg of int * int
| Mul of int * int
let evaluate = function
| Sum(a,b) -> a + b
| Avg(a,b) -> a + b / 2
| Mul(a,b) -> a * b
As commented you left out the evaluation of the expression. 如评论所述,您遗漏了对表达式的评价。 Also there's no reason for using
printfn "%A"
, since we know the return type. 也没有理由使用
printfn "%A"
,因为我们知道返回类型。
Sum(5,10) // Expr
|> evaluate // int
|> printfn "%i" // unit
In your second attempt you're mixing things up a bit. 在你的第二次尝试中你会混淆一些东西。
type Expr = int -> int -> int
As Lee (again) correctly points out, this signature represents a function with 2 arguments. 正如李(再次)正确指出的那样,这个签名代表一个带有2个参数的函数。
let add : Expr = fun a b -> a + b
Or shorthand 或速记
let add : Expr = (+)
As Expr
represents an arithmetic operator, following evaluate function combines them. 由于
Expr
表示算术运算符,因此以下evaluate函数将它们组合在一起。
let evaluate (a : Expr) (b : Expr) =
match a,b with
| a,b -> (fun a -> a + b)
For example: (1 + 2) * (3 + 4) 例如:(1 + 2)*(3 + 4)
type Expr =
| Cte of int
| Add of Expr * Expr
| Mul of Expr * Expr
let rec eval = function
| Cte(i) -> i
| Add(a,b) -> eval a + eval b
| Mul(a,b) -> eval a * eval b
Mul( Add(Cte 1,Cte 2) , Add(Cte 3,Cte 4) )
|> eval
|> printfn "%i"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.