function - 有没有办法让函数根据输入返回整数或字符串?

标签 function types f# return-type

我收到了这份作业(无法添加作业标签)。这只是一个训练问题,不是交接的一部分。 我创建了一个递归函数“eval”,用于评估整数上的常见操作(+、-、*、/) 到目前为止,该函数可以计算加法、乘法和减法。

type expr =
    | Const of int
    | Add of expr * expr
    | Mul of expr * expr
    | Sub of expr * expr

let rec eval (n: expr): int =
    match n with
        | Const n -> n
        | Add (a, b) -> eval a + eval b
        | Mul (a, b) -> eval a * eval b
        | Sub (a, b) -> eval a - eval b

这个功能完美运行。接下来,我必须扩展 expr 类型,以允许除法,添加:

| Div of expr * expr

我还需要通过创建一个新类型来处理零除的情况:

('a, 'b) result

这是 eval 的新返回类型(这是在赋值描述中,所以我必须这样做)。 这是我的尝试:

type ('a, 'b) result =
    | Ok of int
    | Err of string

let rec eval (n: expr): ('a, 'b)result =
    match n with
        | Const n -> Ok(Const n)
        | Add (a, b) -> Ok(eval a + eval b)
        | Mul (a, b) -> OK(eval a * eval b)
        | Sub (a, b) -> Ok(eval a - eval b)
        | Div (_, Const 0) -> Err "zero division"
        | Div (a, b) -> Ok(eval a / eval b)

但我收到一条错误消息,指出运算符 +、-、* 和/没有为类型 ('a, 'b) 结果定义,这是有道理的。所以我的问题是,有没有办法让新类型继承其他类型?我无法输入以下内容:

type ('a, 'b) result =
    | int
    | Err of string

为什么这不是一件事?如果我在新类型中使用 int ,是否必须指定一些与 int 相关联的关键字? f# 想要相同的输出类型,无论输入如何,有办法解决这个问题吗?如果我没有创建新类型,我可以告诉函数输出是整数还是字符串吗?

最佳答案

简短的回答是否定的。 正如您所说,F# 只允许一种返回类型。

在这种情况下,您的 result 类型有 2 组可能的值:Ok 值和 Error 值。 您的代码需要考虑这两种可能性,不能忽略其中一种。 请记住,eval a不再返回int,现在它返回一个结果,该结果可能有也可能没有int 里面。

eval aeval b之后但在调用+-之前* /,您需要检查任一结果是否为 Error。只有当两者都Ok 时,您才能应用该运算符。如果其中任何一个是错误,您就必须返回错误,对吗?

您可以使用match来检查(并提取int),例如:

match eval  a , eval  b  with
|     Ok    a', Ok    b' -> Ok(a' + b')
|     Error e , _    
|     _       , Error e  -> Error e

请记住,您无需将上述说明复制 4 次。 您可以创建一个函数并将运算符作为参数传递 使用以下语法:(+)(-)(*)(/)

另一个提示:您只考虑除以 Const 0 的情况。 如果除以计算出的 0(例如 5/(1 - 1)),会发生什么?

在函数式编程中,还有另一种方法来处理这个问题。 您最终需要的是一个Bind 函数(或Apply>)。 这个网站是一个了解它的好资源:https://fsharpforfunandprofit.com/rop/

关于function - 有没有办法让函数根据输入返回整数或字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64578253/

相关文章:

f# - The Little ML'er - F# 的良好培训?

arrays - RabbitMQ 和 F# - 如何 'read' MQ 消息并将内容拆分为变量或数组?

c# - 使用对象类型的字符串名称在 C# 中进行类型转换

c++ - 将 int8 解释为两个 int4

function - 神经激活函数 - Logistic/Tanh/等之间的差异

html - Angular - 使用 *ngfor 时未定义的属性,(更改)

c# - 当类型仅在执行时已知时调用泛型函数

f# - 如何在 F# 交互式中查看运算符的类型?

javascript - 为什么像这段代码中那样将函数添加为对象属性时省略 () ?

Python + pyQT - 将参数发送到连接的 Signal 函数