F# 函数类型
F# function types
我正在练习 f# 并找到了这个示例,我必须在其中编写以下类型的 f# 函数:
fun1: 'a -> ('a -> 'b) -> 'b
fun2: ('a -> 'b) -> (('a -> 'c) -> 'd) -> ('b -> 'c) -> 'd
fun3: ('a -> 'b -> 'c) -> 'a * 'b -> 'c
fun4: ('a -> 'b -> 'a) -> 'a * 'b -> 'a
fun5: ('a -> 'a -> 'a) -> 'a * 'a -> 'a
我目前的解决方案
// fun1: ’a -> (’a -> ’b) -> ’b
let fun1 x k = k x
// fun2: (’a -> ’b) -> ((’a -> ’c) -> ’d) -> (’b -> ’c) -> ’d
let fun2 f t k = failwith "Not implemented"
// fun3: (’a -> ’b -> ’c) -> ’a * ’b -> ’c
let fun3 f (x, y) = f x y
// fun4: (’a -> ’b -> ’a) -> ’a * ’b -> ’a
let fun4 f (x, y) = failwith "Not implemented"
// fun5: (’a -> ’a -> ’a) -> ’a * ’a -> ’a
let fun5 f (x, y) = failwith "Not implemented"
而且我已经成功完成了 fun1 和 fun 3,其他的需要帮助。任何人都可以给我一些提示吗?谢谢
我将添加一些提示而不是发布解决方案:
// fun2: (’a -> ’b) -> ((’a -> ’c) -> ’d) -> (’b -> ’c) -> ’d
let fun2 f t k = failwith "Not implemented"
这里,f
是'a -> 'b
类型,k
是'b -> 'c
类型。请注意,您可以组合这两个。这样,您就应该能够调用需要 'a -> 'c
.
类型参数的函数 t
// fun5: (’a -> ’a -> ’a) -> ’a * ’a -> ’a
let fun5 f (x, y) = failwith "Not implemented"
这里,函数得到一个函数 f
,可以用两个 'a
类型的参数调用它来产生 'a
类型的结果。您还有两个可以使用的参数,x
和 y
(作为元组传递)。该类型的结构与 fun3
中的结构非常相似,但如果您想在不使用类型注释的情况下编写此函数,您将需要以某种方式让编译器相信所有类型参数都是相同的,即, 'a
。您可以通过多次调用 f
来做到这一点。如果你在一个地方调用 f x y
而在另一个地方调用 f y x
,编译器就会知道 x
和 y
的类型必须相同。
// fun4: (’a -> ’b -> ’a) -> ’a * ’b -> ’a
let fun4 f (x, y) = failwith "Not implemented"
这再次类似于 fun3
和 fun4
,但同样 - 要在没有类型注释的情况下执行此操作 - 您需要以某种方式说服编译器 f
与它 returns 的类型相同。执行此操作的最佳方法是将 f
的结果传递回 f
(作为另一个调用中的第一个参数)。这迫使编译器统一类型。
重要的是你要理解你得到的执行,托马斯很好地解释了一切。 Anymay 这里有一些解决方案,你可以如何做到这一点。或者至少,我将如何解决它。
(* fun1: ’a -> (’a -> ’b) -> ’b *)
let fun1 x f =
f x
(* fun2: (’a -> ’b) -> ((’a -> ’c) -> ’d) -> (’b -> ’c) -> ’d *)
let fun2 f h g =
h (f >> g)
(* fun3: (’a -> ’b -> ’c) -> ’a * ’b -> ’c *)
let fun3 f (x,y) =
f x y
(* fun4: (’a -> ’b -> ’a) -> ’a * ’b -> ’a *)
let fun4 (f : 'a -> 'b -> 'a) (x,y) =
f x y
(* fun5: (’a -> ’a -> ’a) -> ’a * ’a -> ’a *)
let fun5 (f : 'a -> 'a -> 'a) (x,y) =
f x y
一样有趣side-note。 fun1
基本上是 F# 中的 |>
函数或运算符。
证明:
let add1 x = x + 1
printfn "%d" ((|>) 10 add1)
printfn "%d" (fun1 10 add1)
我正在练习 f# 并找到了这个示例,我必须在其中编写以下类型的 f# 函数:
fun1: 'a -> ('a -> 'b) -> 'b
fun2: ('a -> 'b) -> (('a -> 'c) -> 'd) -> ('b -> 'c) -> 'd
fun3: ('a -> 'b -> 'c) -> 'a * 'b -> 'c
fun4: ('a -> 'b -> 'a) -> 'a * 'b -> 'a
fun5: ('a -> 'a -> 'a) -> 'a * 'a -> 'a
我目前的解决方案
// fun1: ’a -> (’a -> ’b) -> ’b
let fun1 x k = k x
// fun2: (’a -> ’b) -> ((’a -> ’c) -> ’d) -> (’b -> ’c) -> ’d
let fun2 f t k = failwith "Not implemented"
// fun3: (’a -> ’b -> ’c) -> ’a * ’b -> ’c
let fun3 f (x, y) = f x y
// fun4: (’a -> ’b -> ’a) -> ’a * ’b -> ’a
let fun4 f (x, y) = failwith "Not implemented"
// fun5: (’a -> ’a -> ’a) -> ’a * ’a -> ’a
let fun5 f (x, y) = failwith "Not implemented"
而且我已经成功完成了 fun1 和 fun 3,其他的需要帮助。任何人都可以给我一些提示吗?谢谢
我将添加一些提示而不是发布解决方案:
// fun2: (’a -> ’b) -> ((’a -> ’c) -> ’d) -> (’b -> ’c) -> ’d
let fun2 f t k = failwith "Not implemented"
这里,f
是'a -> 'b
类型,k
是'b -> 'c
类型。请注意,您可以组合这两个。这样,您就应该能够调用需要 'a -> 'c
.
t
// fun5: (’a -> ’a -> ’a) -> ’a * ’a -> ’a
let fun5 f (x, y) = failwith "Not implemented"
这里,函数得到一个函数 f
,可以用两个 'a
类型的参数调用它来产生 'a
类型的结果。您还有两个可以使用的参数,x
和 y
(作为元组传递)。该类型的结构与 fun3
中的结构非常相似,但如果您想在不使用类型注释的情况下编写此函数,您将需要以某种方式让编译器相信所有类型参数都是相同的,即, 'a
。您可以通过多次调用 f
来做到这一点。如果你在一个地方调用 f x y
而在另一个地方调用 f y x
,编译器就会知道 x
和 y
的类型必须相同。
// fun4: (’a -> ’b -> ’a) -> ’a * ’b -> ’a
let fun4 f (x, y) = failwith "Not implemented"
这再次类似于 fun3
和 fun4
,但同样 - 要在没有类型注释的情况下执行此操作 - 您需要以某种方式说服编译器 f
与它 returns 的类型相同。执行此操作的最佳方法是将 f
的结果传递回 f
(作为另一个调用中的第一个参数)。这迫使编译器统一类型。
重要的是你要理解你得到的执行,托马斯很好地解释了一切。 Anymay 这里有一些解决方案,你可以如何做到这一点。或者至少,我将如何解决它。
(* fun1: ’a -> (’a -> ’b) -> ’b *)
let fun1 x f =
f x
(* fun2: (’a -> ’b) -> ((’a -> ’c) -> ’d) -> (’b -> ’c) -> ’d *)
let fun2 f h g =
h (f >> g)
(* fun3: (’a -> ’b -> ’c) -> ’a * ’b -> ’c *)
let fun3 f (x,y) =
f x y
(* fun4: (’a -> ’b -> ’a) -> ’a * ’b -> ’a *)
let fun4 (f : 'a -> 'b -> 'a) (x,y) =
f x y
(* fun5: (’a -> ’a -> ’a) -> ’a * ’a -> ’a *)
let fun5 (f : 'a -> 'a -> 'a) (x,y) =
f x y
一样有趣side-note。 fun1
基本上是 F# 中的 |>
函数或运算符。
证明:
let add1 x = x + 1
printfn "%d" ((|>) 10 add1)
printfn "%d" (fun1 10 add1)