How to use List.map in OCaml

人走茶凉 提交于 2020-01-05 03:44:52

问题


I have a list of lists in OCaml returning [[7; 5]; [7; 3; 2]]. I know there's a lot of List functions in OCaml. I want to print each value out with a plus sign between them like one would do in Python or Ruby. In Python, I do this with print('+'.join(map(str,lst))) where lst is the list, str is to convert to a string. How do I do this in OCaml?

Console Input

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

Console Output

7 + 5
7 + 3 + 2

UPDATE

let main num = 
    print_string "Prime Partitions Program" in
    print_linked_list (prime_part num (all_primes 2 num)) ;;

I have a wrapper function main. It calls all 3 functions for everything to work. However, the interpreter is giving me an unbound value num. prime_part is a function that gives the linked list back as shown in the console input. all_primes is a function that serves as input to prime_part. How can I make these functions feed as input to the print_linked_list function?


回答1:


Here's a function that prints an int list list with plus signs:

let pll ll =
    let pl l =
        print_endline (String.concat " + " (List.map string_of_int l))
    in
    List.iter pl ll

Here's how it looks for your example:

val pll : int list list -> unit = <fun>
# pll [[7; 5]; [7; 3; 2]];;
7 + 5
7 + 3 + 2
- : unit = ()



回答2:


The str.join method corresponds to OCaml's String.concat. So python's

"+".join(["1", "2", "3"])

maps to

String.concat "+" ["1"; "2"; "3"]

Same as join, the concat function will work only on lists of strings, so if we have values of some other type we should map them to string. Unlike Python, in OCaml doesn't have a str function that works for all values, as OCaml, in general, doesn't support, so called, ad-hoc polymorphism. So for each type, there is a separate function that transforms it to its values to string representations. For example, for integers, it is the string_of_int function. So, the following Python code

"+".join(str(x) for x in [1, 2, 3])

Can be translated into OCaml, as follows:

[1;2;3] |> List.map string_of_int |> String.concat "+"

We can generalize it to a function

let join string_of_element sep xs = 
  xs |> List.map string_of_element |> String.concat sep

With such generic function we can easily solve your problem:

let join_ints_with = join string_of_int
let sum_of_ints = join_ints_with "+"
let string_of_equations = join sum_of_ints "\n"
let print_equations eqs = print_endline (string_of_equations eqs)

E.g.,

print_equations [[7; 5]; [7; 3; 2]];;
7+5
7+3+2



回答3:


Well first let's try to think of a way to take a single list and join it with a + character. We can do this by simple recursion. One implementation could look like this:

let join_with_plus lst =    
  let rec join lst acc =
    match lst with   
    | [] -> acc
    | n :: [] -> acc ^ (string_of_int n)
    | n :: rest -> inner_join rest (acc ^ (string_of_int n) ^ " + ")
  in join lst ""

Now that we have this piece of the puzzle, we just need to apply this to each of the lists in your list.

Here, we can use the List.fold_left function to iterate over our list of lists, and building up our new list of strings as we go along.

let stringify_all_lists lst = 
  List.fold_left (fun acc lst -> (join_plus lst) :: acc) [] lst

So our final product would look something like this:

stringify_all_lists [[7; 5]; [7; 3; 2]]
(* string list = ["7 + 5"; "7 + 3 + 2"] *)


来源:https://stackoverflow.com/questions/42127372/how-to-use-list-map-in-ocaml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!