Generics 当您不关心返回值时,创建可适应的泛型返回类型的首选方法是什么?

Generics 当您不关心返回值时,创建可适应的泛型返回类型的首选方法是什么?,generics,f#,Generics,F#,假设您想要创建一个具有最终副作用的函数,它会引发错误、退出程序、飞往月球,那么正确的模式是什么?我现在是这样做的: let fastExit x = match box x with | null -> System.Environment.FailFast("Something went terribly wrong, get out fast!") Unchecked.defaultof<_> // adaptable ge

假设您想要创建一个具有最终副作用的函数,它会引发错误、退出程序、飞往月球,那么正确的模式是什么?我现在是这样做的:

let fastExit x =
    match box x with
    | null ->
        System.Environment.FailFast("Something went terribly wrong, get out fast!")
        Unchecked.defaultof<_>  // adaptable generic return
    | _ -> x
let fastExit x =
    if isNull x then nullArg "x"
    elif otherGenericCheck x then failwith "x Didn't pass other generic check"
    // More generic checks
    x
我经常遵循上述模式,特别是在与CLR的BCL交互时,但从未真正怀疑这是否是F的做事方式。显然,这只适用于永远不返回的情况,或者在执行代码时不必关心危险的返回值的情况


请注意,正如现已删除的注释所建议的,这在可组合性和可链接性方面也有意义,即使用compose>>和pipe |>操作符。

您可以将示例改写为:

let fastExit x = 
    if box x = null then // not the most efficient to way to check for null, but whatever
       System.Environment.FailFast("Oh noes!")
    x
如果您调用该函数以获取它将抛出的异常,这也可以使用。但不确定飞向月球的功能


这将是一般的方法:您正在编写命令式代码,所以请以命令式的方式编写。

我会这样写:

let fastExit x =
    match box x with
    | null ->
        System.Environment.FailFast("Something went terribly wrong, get out fast!")
        Unchecked.defaultof<_>  // adaptable generic return
    | _ -> x
let fastExit x =
    if isNull x then nullArg "x"
    elif otherGenericCheck x then failwith "x Didn't pass other generic check"
    // More generic checks
    x
请注意,编译器已经将x的类型限制为null值

如果您选中它,您将检查任何类型,包括那些使用内部null作为“有效”值表示的类型,这意味着如果您传递一个选项类型,并且它的值为None,那么它将失败

所以拳击与否取决于这一点


当然,如果唯一的检查是空检查,我根本不会写这个函数,我想我们都同意这一点,除非有一种情况,你想要有t效应,例如当用|>链接许多函数时。

我可能会把failwith放在编译器上happy@JohnPalmer,您的意思是将failwith放在需要执行的代码之后,例如,在本例中,放在FailFast之后。在某些情况下,如果你确实不想退出,那是不可行的。不过,不可否认,那将是危险的代码。我可能会这么做do@JohnPalmer,我想你的建议在某种程度上是有道理的。例如,如果你犯了一个错误,至少你会得到一个有意义的错误。是的,这是编写示例的另一种方式,可以说是一种更好的方式,但我经常发现自己避免使用if-then,这一定是我的声明式编程背景。但我的意思是,我的问题更一般,例如,我还有签名单元->'a,在这里我用Unchecked.defaultOf强制执行'a。好吧,一般来说,我的建议是,编写它时不要返回代码路径,而不是返回一个无意义或潜在危险的值,比如null,只是为了取悦编译器。F为您提供了编写命令式代码的工具,因此,如果您正在编写命令式逻辑,请利用它们。感谢您对boxing的评论,但是如果我添加了isNull,它肯定有它的用途,那么我就失去了您在回答中提到的泛型。此外,我有不同签名的情况,即“a->”b或“单位->”a或其他。但我认为你基本上是正确的,如果你不希望达到那个程序点,那么最好从带有failwith的函数返回。对不起,我没有听清楚你所说的不同签名,比如unit->'a。你能再解释一下吗?我对unit->'a的意思是,例如,一个类似exit的函数,它的退出代码为零。或者从中,方法是unit->unit,但是包含的函数应该有unit->'a,类似于reraise函数。