【问题标题】:Type mismatch with pattern matching类型与模式匹配不匹配
【发布时间】:2014-12-08 13:44:02
【问题描述】:

我有一个运行良好的代码:

let rec calculate s l acc =
    if length s = 0 then
        acc
    else
        if first s = l then
            calculate (rest s) l (acc+1)
        else
            calculate (rest s) (first s) acc

我想用模式匹配重写它:

let rec calculate s l acc =
    function
    | _, _, _ when length s = 0 -> acc
    | _, _, _ when first s = l  -> calculate (rest s) l (acc+1)
    | _, _, _                   -> calculate (rest s) (first s) acc

但是最后一个函数返回错误信息:

  | _, _, _ when first s = l  -> calculate (rest s) l (acc+1)   -----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/Users/demas/temporary/stdin(512,36):错误 FS0001:类型不匹配。 期待一个 'a 但给定一个 'b * 'c * 'd -> 'a 统一 ''a' 和 ''b * 'c * 'd -> 'a' 时产生的类型是无限的

为什么?

【问题讨论】:

  • 这是一种模式匹配并没有真正带来任何东西的情况。我只会使用您的原始代码,使用elif 而不是else if 以避免缩进太深,仅此而已。

标签: f#


【解决方案1】:

关键字 function 意味着函数 calculate 的最后一个(隐式)参数应该是包含 3 个元素的元组,因为您正在匹配 _、_、_ 您可以将其重写为:

let rec calculate s l acc =
    match s, l, acc with
    | _, _, _ when length s = 0 -> acc
    | _, _, _ when first s = l  -> calculate (rest s) l (acc+1)
    | _, _, _                   -> calculate (rest s) (first s) acc

你也可以让模式匹配更清晰地重写它:

let rec calculate s l acc =
    match (length s), (first s = l) with
    | 0, _    -> acc
    | _, true -> calculate (rest s) l (acc+1)
    | _, _    -> calculate (rest s) (first s) acc

【讨论】:

  • 谢谢。但是为什么它重复这条正确的行'when first s = l -> calculate (rest s) l (acc+1)' 而不是错误消息中的前一个?
  • 这是因为模式匹配的所有分支都应该属于同一类型。编译器推断这种类型应该是'a(参数'acc'的通用类型)-第一个分支的类型,因为类型推断是从上到下发生的。这就是它在第二个分支上给出类型错误的原因。
  • 我还添加了更短且更有意义的模式匹配代码
  • 正如我所见,它不是等效的代码。如果 s 的长度为零,则 'first' 函数返回错误。但是,是的,我当然可以重写我的“第一个”函数。
猜你喜欢
  • 2014-02-05
  • 2020-11-15
  • 1970-01-01
  • 2016-10-29
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 2020-08-09
  • 2018-06-08
相关资源
最近更新 更多