代码之家  ›  专栏  ›  技术社区  ›  Benoît Guédas

为什么我不能标记一个只引发异常的函数的参数?

  •  0
  • Benoît Guédas  · 技术社区  · 10 年前

    我正在尝试编写一个只引发异常的函数。它可以工作,但当参数被标记时,我不能在另一个函数中使用它。

    下面是一个简单的例子:

    let raise_error ~m = failwith m
    
    let test = function
      | true -> raise_error "ok"
      | false -> raise_error "ko"
    

    有一个警告,并且函数没有我期望的类型:

    Warning 20: this argument will not be used by the function.
    Warning 20: this argument will not be used by the function.
    val test : bool -> m:string -> 'a = <fun>
    

    此其他函数无法编译:

    let test2 = function
      | true -> "ok"
      | false -> raise_error "ko"
    

    带有以下信息:

    Warning 20: this argument will not be used by the function.
    Error: This expression has type m:string -> 'a
    but an expression was expected of type string
    

    我不明白哪里出了问题,因为如果论点没有被标记,它就会起作用。

    有没有办法解决这个问题?

    1 回复  |  直到 10 年前
        1
  •  3
  •   gsg    10 年前

    您可以在调用站点标记参数:

    let raise_error ~m = failwith m
    
    let test = function
      | true -> raise_error ~m:"ok"
      | false -> raise_error ~m:"ko"
    
    let test2 = function
      | true -> "ok"
      | false -> raise_error ~m:"ko"
    

    更好的解决方案是重写 raise_error 不使用带标签的参数。

    问题是 原因_错误 写的有一种类型 m:string -> 'a ,因此可以传递任意数量的非标记参数,结果表达式仍然是类型为的函数 m: 字符串->'一 。这很容易出错,而且令人惊讶,因此应避免将带标签的参数与发散函数一起使用。