代码之家  ›  专栏  ›  技术社区  ›  natemcintosh

递归模式匹配的返回类型

f#
  •  0
  • natemcintosh  · 技术社区  · 4 年前

    我刚开始学F#,为了提高我的技能,我正在尝试 2019 Advent of Code . 我正在尝试第二天的第一个谜题,结果被卡住了。看下面第二天的规则。

    我想我遇到的问题是我不太明白编译器是如何计算递归函数的返回类型的。请看我的尝试:

    let rec intcode (arr: int []) op = // int [] -> int -> int []
        let in1 = op + 1
        let in2 = op + 2
        let out = op + 3
        match arr.[op] with
        | 1 ->
            arr.[arr.[out]] <- arr.[arr.[in1]] + arr.[arr.[in2]]
            intcode arr op+4
        | 2 ->
            arr.[arr.[out]] <- arr.[arr.[in1]] * arr.[arr.[in2]]
            intcode arr op+4
        | 99 -> 
            arr
        | _ -> 
            printfn "Had input operator that was not 1, 2, or 99"
            arr
    

    编译器给我在函数开始处注释的函数签名, int [] -> int -> int []

    但是,编译器还告诉我,在尝试返回 arr 当匹配图案时 99 , error FS0001: The type 'int' does not match the type 'int []'

    它告诉我它认为 阿里尔 int ? 或者它认为函数的输出应该是 内景 ?

    规则

    Intcode程序是由逗号分隔的整数列表(如1、0、0、3、99)。要运行一个,首先查看第一个整数(称为位置0)。在这里,您将找到一个操作码-1、2或99。操作码指示要做什么;例如,99表示程序已完成,应立即停止。遇到未知的操作码意味着出了问题。

    例如,如果您的Intcode计算机遇到1,10,20,30,它应该读取位置10和20处的值,将这些值相加,然后用它们的和覆盖位置30处的值。

    操作码2的工作原理与操作码1完全相同,只是它将两个输入相乘而不是相加。同样,操作码后面的三个整数表示输入和输出的位置,而不是它们的值。

    处理完操作码后,向前移动4个位置,转到下一个位置。

    1 回复  |  直到 4 年前
        1
  •  1
  •   glennsl Namudon'tdie    4 年前

    问题不在于(直接)类型推断,而在于 operator precedence .

    intcode arr op+4
    

    被解析为

    (intcode arr op)+4
    

    intcode arr (op+4)
    

    因为函数应用程序比 +

    根据前面的分组,编译器推断表达式必须是 int 因为最外层的表达式是 添加。

    要解决这个问题,只需在周围添加括号 op+4