我在教自己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:?
答案 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
}
是的!因此,类型签名上的注释并不重要,因为类型签名是等价的。