Как мне инициализировать мой список кортежей - PullRequest
0 голосов
/ 20 октября 2019

У меня есть функция, которая берет список кортежей и обрабатывает его, чтобы получить кортеж из 3 целых чисел. Теперь я хотел бы проверить его со списком созданного мной типа кортежей, но не могу создать этот список.

Вот мой тип кортежа:

    type t_votes = {valeur : string ; nombre : int };;

Вот мойfunction:

let rec recap (l : t_votes list) : int * int * int =
    let (nb_oui,nb_non,nb_blanc) = recap(tl(l)) in
    if (l=[]) then
       (0,0,0)
    else if ((hd(l)).valeur = "oui") then
       (nb_oui+(hd(l)).nombre ,nb_non,nb_blanc)
    else if ((hd(l)).valeur = "non") then
       (nb_oui, nb_non + (hd(l)).nombre, nb_blanc)
    else if ((hd(l)).valeur = "blanc") then
       (nb_oui,nb_non,nb_blanc+(hd(l)).nombre)
    else
       failwith("liste invalide")
;;

А вот моя тщетная попытка объявить список для проверки моей функции:

let liste_votes : t_votes list = [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)];;
recap(liste_votes );;

Вот что дает мне туарег:

# let liste_votes : t_votes list = [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)];;
Characters 34-45:
  let liste_votes : t_votes list = [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)];;
                                    ^^^^^^^^^^^
Error: This expression has type 'a * 'b
       but an expression was expected of type t_votes

1 Ответ

0 голосов
/ 20 октября 2019

Чтобы создать значение типа записи (поскольку это тип записи, а не кортеж, кортеж не называет свои аргументы), используется следующий синтаксис:

{ valeur = "Some string" ; nombre = 13 }

Если этоСинтаксис слишком тяжел для вас, обычной практикой является написание функции построителя:

let mk_vote valeur nombre = { valeur ; nombre }

Здесь я использую другой фрагмент синтаксиса для создания экземпляра значения записи без использования символа =. В этом случае это то же самое, что написать valeur = valeur и nombre = nombre.

. Затем вы можете написать:

let votes = [ mk_vote "oui" 120 ; mk_vote "non" 18 ; mk_vote "blanc" 20 ; mk_vote "oui" 20 ; mk_vote "non" 24 ; mk_vote "blanc" 25 ]
let mk_vote (valeur, nombre) = { valeur ; nombre }

будет работать и позволит вам написать

let votes = List.map mk_vote [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)]

Для некоторых vote типа записи вы можете получить доступ к полям с помощью vote.valeur и vote.nombre. Вы также можете использовать сопоставление с образцом:

match vote with
| { valeur = v ; nombre = n } => (* ... *)

Вы также можете создать значение записи из другого, например:

let vote = { valeur = "Some string" ; nombre = 13 } in
let vote' = { vote with valeur = "Some other string" } in
(* ... *)

Тогда vote'.valeur равно "Some other string", в то время как vote'.nombre это vote.nombre или 13 в этом случае.


Наконец, я не мог не заметить, что вы использовали строки для представления различного рода голосов, так как, кажется, всего три случаявыделенный тип был бы более уместным (в конце концов, вы используете ocaml, который позволяет правильно обрабатывать данные).

type vote_kind =
| Yes
| No
| Blank

type t_votes = {
  value : vote_kind ;
  amount : int ;
}
...