我想将这个ML代码翻译成F#.
fun take ([], i) = []
| take (x::xs, i) = if i > 0 then x::take(xs, i-1)
else [];
Run Code Online (Sandbox Code Playgroud)
我试过这个
let rec take n i =
match n,i with
| [], i -> []
| x::xs, i -> if i > 0 then x::take(xs, i-1)
else [];
let val = take [1;2;3;4] 3
Run Code Online (Sandbox Code Playgroud)
还有这个
let rec take input =
match input with
| ([], i) -> []
| (x::xs, i) -> if i > 0 then x::take(xs, i-1)
else [];
let val = take ([1;2;3;4] 3)
Run Code Online (Sandbox Code Playgroud)
但他们两个都给我一个错误take.fs(7,5): error FS0010: Unexpected keyword 'val' in binding
.F#代码有什么问题?
只是添加一些注释,我认为在F#中编写函数的最好方法是使用:
let rec take i n=
match n, i with
| [], i -> []
| _, i when i <= 0 -> []
| x::xs, i -> x::(take (i-1) xs)
Run Code Online (Sandbox Code Playgroud)
我做了两个改动:
i <= 0
(它做同样的事情if
,但看起来更好)反转参数的顺序,以便最重要的参数(输入列表)是最后一个.这使得可以很好地使用该功能与流水线操作符:
[1;2;3;4] |> take 3
Run Code Online (Sandbox Code Playgroud)由于val
是F#中的保留关键字,因此不能将其用作值.您的第一个版本take
是错误的,因为take(xs, i-1)
(元组形式)的类型与take n i
(咖喱形式)的类型不同.这有效:
let rec take n i =
match n, i with
| [], i -> []
| x::xs, i -> if i > 0 then x::(take xs (i-1)) else []
let value = take [1;2;3;4] 3
Run Code Online (Sandbox Code Playgroud)
第二个版本在调用函数时出错.它可以修复如下:
let rec take input =
match input with
| [], i -> []
| x::xs, i -> if i > 0 then x::take(xs, i-1) else []
let value = take ([1;2;3;4], 3) // Notice ',' as tuple delimiter
Run Code Online (Sandbox Code Playgroud)
或者你可以写得更接近你的ML功能:
let rec take = function
| [], i -> []
| x::xs, i -> if i > 0 then x::take(xs, i-1) else []
let value = take ([1;2;3;4], 3)
Run Code Online (Sandbox Code Playgroud)