F# 命名函数本身在F中为参数的参数#

F# 命名函数本身在F中为参数的参数#,f#,naming,code-documentation,F#,Naming,Code Documentation,给函数参数命名是记录代码的一种方式;如果没有这种需要,那么我们可以给他们起“arg1”和“arg2”这样的名字,而且不会更糟——但事实上,这当然会让我们的代码更难理解。在F#中,我们经常将函数作为参数传递给其他函数,在这种情况下,它们的参数不再命名: let foo<'T> (bar : 'T -> 'T -> float -> 'T) = // do something let foo'T->float->T)= //做点什么 这个函数foo接受一个“

给函数参数命名是记录代码的一种方式;如果没有这种需要,那么我们可以给他们起“arg1”和“arg2”这样的名字,而且不会更糟——但事实上,这当然会让我们的代码更难理解。在F#中,我们经常将函数作为参数传递给其他函数,在这种情况下,它们的参数不再命名:

let foo<'T> (bar : 'T -> 'T -> float -> 'T) =
    // do something
let foo'T->float->T)=
//做点什么
这个函数foo接受一个“bar”作为参数,它本身接受两个'T和一个float并返回一个'T,但是很难判断它应该做什么。如果我们能将“bar”的参数命名为:

let foo<'T> (bar : (startVal : 'T) -> (endVal : 'T) -> (interpolationAmt : float) -> 'T) =
    // do something
let foo(endVal:'T)->(interpolationAmt:float)->'T)=
//做点什么
现在很明显“bar”是用来做什么的:它在两个类型为'T'的值之间插值。此外,'T参数的顺序以及应用它们的顺序也变得很重要。但不幸的是,这段代码无法编译


所以我的问题是,是否有一种方法我错过了,如果没有,人们通常如何处理这个问题?

如果
bar
插值,你可以称之为
interpolate

您还可以使用简单的类型别名作为标记来帮助通信。然而,通过查看
foo
不清楚
StartValue->EndValue endVal:'T->interpolationAmount:float->'T
让我们一起去吧=
()

编辑:另一个选项是使用匿名记录类型:


let foo不幸的是,无法将参数名添加到函数签名中。要使函数签名易于理解,最好的方法是自定义类型。但是我建议只为真正的域类型创建自定义类型,这些域类型本身就有一些意义。通常,此类类型有一些限制-非空列表、最大长度为42的字符串、负整数等。因此,对于您的函数,我将为插值量创建一个类型:

type InterpolationAmount = private InterpolationAmount of float

module InterpolationAmount =
    let create (amount: float) : InterpolationAmount =
        if amount < 0. then failwith "blah-blah"
        else InterpolationAmount amount
当然,使用
bar
以外的名称也会给用户一个提示

let foo<'T> (interpolate : InterpolationArgs<'T> -> 'T) =
     interpolate {
        startValue = a
        endValue = b
        amount = InterpolationAmount.create 1.2
     }
let foo->'T)=
插入{
起始值=a
endValue=b
金额=插值装载量。创建1.2
}

谢谢你的回答,但我不能接受,因为这两个选项都不能使代码更容易阅读:对于第一个选项,将“StartValue”和“EndValue”分类为类型在概念上没有意义,这使得很难一眼就理解函数签名。在我看来,面向对象的替代方案不像惯用的F#,它使函数更易于使用。我很难想象这两种方式都是F#?@Bent的既定做法。我刚刚添加了使用匿名记录的第三种选择。我认为没有一种官方惯用的方法。这些都被用于这类问题,它们有不同的权衡。谢尔盖的答案也有一些不错的选择。
let foo<'T> (interpolate : InterpolationArgs<'T> -> 'T) =
     interpolate {
        startValue = a
        endValue = b
        amount = InterpolationAmount.create 1.2
     }