1

Define an F# function AppendManually list1 list2 that takes two lists and concatenates them into one. I am not allowed to use the standard F# method (example: @) on lists! For example:

 AppendManually [1; 3; 5] [7]

should return

int list = [1; 3; 5; 7]

.

3 Answers3

2

Typical learner's question, I guess… let's create a typical learner's answer, not using any library functions:

let AppendManually l1 l2 =
    let rec rev acc = function
        | [] -> acc
        | x :: xs -> rev (x :: acc) xs
    rev [] (rev (rev [] l1) l2)

How does it work? Since we cannot append to the end of a list, only prepend to the beginning, we create a helper function rev that takes two lists, and will loop through the second list from beginning to end, prepending all elements to the first list. Once the second list is empty, the first list contains all elements in reverse order.

This function is then used as follows: prepend the elements of the first list to an empty list in reverse order; prepend the elements of the second list in reverse order to the result of the first call; lastly, prepend the result of that in reverse order to an empty list again.

dumetrulo
  • 1,993
  • 9
  • 11
  • 1
    You can simply do: `l1 |> rev [] |> rev l2` or: `rev l2 (rev [] l1)` instead of: `rev [] (rev (rev [] l1) l2)`. – gileCAD Sep 20 '17 at 16:41
1

I believe that List.append would be the convenient way. If you don't want to use that, you could always fold one list onto the other one individually adding elements.

let a =[1; 3; 5]
let b =[7]
b |> List.foldBack (fun e acc->  e :: acc) a
Asier Azkuenaga
  • 1,199
  • 6
  • 17
1

I sorted it out:

let rec AppendManually list1 list2= 
  match list1,list2 with
  | [],l | l,[] -> l
  | x::list1', y::list2' -> 
     if x < y then x :: (AppendManually list1' list2) 
     else y :: (AppendManually list1 list2')    
  • 2
    Why do you have `if x < y` in there? Does the assignment also tell you that the two lists should end up in sorted order? Because if you're just supposed to append two lists, that will give you the wrong result. Consider this: what should `AppendManually [1; 3; 5] [2; 4; 6]` return? Your function would return `[1; 2; 3; 4; 5; 6]`, but the right answer should be `[1; 3; 5; 2; 4; 6]` if you're supposed to just append and not sort. – rmunn Sep 20 '17 at 07:49
  • Besides, this answer is not tail-recursive, and would fail with a large list w/ a stackoverflow – Fabio Marreco Sep 21 '17 at 15:25