功能类型参数标签是否重要

时间:2017-03-21 01:53:01

标签: f#

我在教自己F#。我的问题来自于我在“使用F#进行功能编程”一书中解决练习2.13的问题,该书要求我将函数curry定义为:

curry : ('a * 'b -> 'c) -> 'a -> 'b -> 'c

我目前的结果是

curry : f:('a * b' -> 'c) -> x:'a -> y:'b -> 'c

问题 参数标签是否重要?我的解决方案是正确的,还是正确的解决方案没有标签f:,x:和y:?

2 个答案:

答案 0 :(得分:3)

不,参数标签对于本练习的解决方案无关紧要,这就是它们被排除在预期解决方案之外的原因。定义为let curry f x y = ...的函数和定义为let curry funcToCurry firstParam secondParam = ...的函数都是有效的解决方案,只要它们做正确的事情。这个练习中最重要的是结果函数的形状(即它所采用和返回的类型),而不是你给它的参数的名称。

答案 1 :(得分:2)

从功能的角度来看(如何,它是如何工作的,而不是在函数式编程中),重要的是它们是否是等价的。测试这个的方法是看两者是否可以互换。

让我们假装您定义了这样的函数(注意类型签名与您的匹配):

let makeCurried (f: ('a * 'b -> 'c)->'a->'b->'c) g : ('a -> 'b -> 'c) = f g;;

val makeCurried :
  f:(('a * 'b -> 'c) -> 'a -> 'b -> 'c) ->
    g:('a * 'b -> 'c) -> ('a -> 'b -> 'c)

然后,让我们定义第二个函数,它接受所需类型签名的函数,如下所示:

makeCurried

请注意('a * 'b -> 'c) -> 'a -> 'b -> 'c的第一个参数采用curry类型的函数。

现在测试是:您可以将makeCurried函数传递给makeCurried curry (fun (x,y)->x*y);; val it : (int -> int -> int) = <fun:it@7> 作为第一个参数吗?如果是这样,那么两者是等价的。

func sha256(string: String) -> [UInt8] {
    var digest = [UInt8](count: Int(CC_SHA256_DIGEST_LENGTH), repeatedValue: 0)
    if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
        CC_SHA256(data.bytes, CC_LONG(data.length), &digest)
    }
    return digest
}

是的!因此,类型签名上的注释并不重要,因为类型签名是等价的。