gpt4 book ai didi

F# kprintf : missing warning about about redundant arguments

转载 作者:行者123 更新时间:2023-12-05 00:42:30 25 4
gpt4 key购买 nike

有没有办法使用 kprintf(或类似的)对异常进行字符串格式化,并且仍然会收到有关冗余参数的警告?到目前为止,我有:

type MyException (s:string) = 
inherit System.Exception(s)
static member Raise msg =
Printf.kprintf (fun s -> raise (MyException(s))) msg

do
MyException.Raise "boom %d" 9 1 // Gives NO warning about redundant arguments
failwithf "boom %d" 9 1 // Gives warning about redundant arguments

我知道我可以使用新的 $ 格式,但希望与旧版本的 F# 保持兼容。

最佳答案

问题不是来自kprintf,而是来自raise,它允许函数的返回类型可以是任意类型,包括柯里化(Currying)函数。函数 failwithf 有这个警告作为一个特例。

如果你返回,比如说,一个字符串或一个单位,你实际上会得到一个错误。缺点是现在你不能再在每个位置加注,因为返回参数不再是通用的。

您可以通过强制使用类型参数来解决此问题,但这会使调用者不太理想。

例如,这是可行的,但是如果您将 f 的返回类型更改为字符串,则会失败:

open System
type MyException (s:string) =
inherit System.Exception(s)
static member Raise msg =
Printf.kprintf (fun s -> raise (MyException s) |> ignore) msg

module Test =
let f() : unit = // string won’t work
MyException.Raise "boom %d" 9 10 // error, as expected

编辑:解决方法

这里有一些解决方法。您可以使用泛型类型约束来限制类型,并利用 F# 函数类型不可比较或不相等、没有正确值 null 的事实。

由于 F# 强大的结构等式支持,您将使用的大多数类型都是可等式的。类型约束的其他选项是 struct(仅结构)、null(这不包括记录和 DU 类型)或特定的继承约束(如果适合您的用例)。

例子:

type MyException (s:string) = 
inherit System.Exception(s)

static member Raise<'T when 'T : equality> msg =
let raiser s =
raise (MyException s)
Unchecked.defaultof<'T> // fool the compiler

Printf.kprintf raiser msg

module Test =
let f() = MyException.Raise "boom %d" 9
let g() = MyException.Raise "boom %d" 9 10 // error

除了类型限制之外,缺点是您得到的错误将是类型错误,而不是您请求的警告。

关于F# kprintf : missing warning about about redundant arguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73284201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com