Implementing F # capture by translating ML equivalent

I would like to translate this ML code to F #.

fun take ([], i) = []
  | take (x::xs, i) = if i > 0 then x::take(xs, i-1) 
                                else [];

I tried this one

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

and this one

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)

But both of them give me an error take.fs(7,5): error FS0010: Unexpected keyword 'val' in binding. What is wrong with the F # code?

+3
source share
2 answers

Since it valis a reserved keyword in F #, you cannot use it as a value. Your first version takeis incorrect, because the type take(xs, i-1)(tuple) is different from the type take n i(curry). It works:

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

The second version has an error in the way you call the function. It can be fixed as follows:

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

Or you can write even closer to your ML function:

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)
+7
source

, , F # - :

let rec take i n=  
  match n, i with
  | [], i -> []
  | _, i when i <= 0 -> []
  | x::xs, i -> x::(take (i-1) xs)

:

  • , , i <= 0 ( , if, )
  • , ( ) . :

    [1;2;3;4] |> take 3
    
+9

All Articles