2017-02-09 8 views
0

У меня есть список списков в OCaml, возвращающий [[7; 5]; [7; 3; 2]]. Я знаю, что в OCaml есть много функций List. Я хочу напечатать каждое значение со знаком «плюс» между ними, как в Python или Ruby. В Python я делаю это с помощью print('+'.join(map(str,lst))), где lst - это список, str - преобразование в строку. Как это сделать в OCaml?Как использовать List.map в 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)) ;; 

У меня есть функция обертку main. Он называет все 3 функции для работы. Однако интерпретатор дает мне несвязанное значение num. prime_part - это функция, которая возвращает связанный список, как показано на вкладке консоли. all_primes - это функция, которая служит для ввода prime_part. Как я могу использовать эти функции в качестве входных данных для функции print_linked_list?

+0

Какая связь между входом и выходом в консоль? '4',' 1' и '6', кажется, выходят из ниоткуда. – gallais

+1

Это были просто случайные числа. Я исправил сообщение, чтобы исправить это. – technogeek1995

ответ

4

Вот функция, которая печатает int list list с плюс признаки:

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

Вот как это выглядит для примера:

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

Хорошо сначала попробуем подумать о способе взять один список и присоединиться к нему с символом +. Мы можем сделать это путем простой рекурсии. Одна реализация может выглядеть следующим образом:

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 "" 

Теперь, когда у нас есть этот кусок головоломки, мы просто должны применить это к каждому из списков в списке.

Здесь мы можем использовать функцию List.fold_left для перебора списка наших списков и создания нашего нового списка строк по мере продвижения.

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

Таким образом, наш конечный продукт будет выглядеть примерно так:

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

Метод str.join соответствует OCaml's String.concat. Так

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

карты Пайтона к

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

То же, что join, функция concat будет работать только со списками строк, так что если у нас есть значения другого типа, мы должны сопоставить их в строку. В отличие от Python, в OCaml нет функции str, которая работает для всех значений, поскольку OCaml, в общем, не поддерживает так называемый ad-hoc-полиморфизм. Таким образом, для каждого типа существует отдельная функция, которая преобразует ее в свои значения в строковые представления. Например, для целых чисел это функция string_of_int.Таким образом, следующий код Python

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

Может быть переведены на OCaml следующим образом:

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

Мы можем обобщить его функции

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

С такой обобщенной функции мы можем легко решение проблемы:

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) 

, например,

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