(* CIS 120 Lecture 3 / 4. Demonstrates basic list operations. *) ;; open Assert (* Collection of songs by Lady Gaga. *) let gaga_songs : string list = [ "Bad Romance"; "Alejandro"; "Monster"; "Speechless"; "Dance in the Dark"; "Telephone"; "So Happy I Could Die"; "Teeth"; "Just Dance"; "Love Game"; "Paparazzi"; "Beautiful, Dirty, Rich"; "Eh, Eh (Nothing Else I Can Say)"; "Poker Face"; "The Fame"; "Money Honey"; "Again Again"; "Boys Boys Boys"; "Brown Eyes"; "Summerboy" ] (* Some sample playlists *) (* Some with Lady Gaga songs, but others too. *) let pl1 : string list = [ "Bad Romance"; "Nightswimming"; "Telephone"; "Everybody Hurts" ] (* Some without any Lady Gaga songs. *) let pl2 : string list = [ "Losing My Religion"; "Man on the Moon"; "Belong" ] (* A playlist with no songs. *) let pl3 : string list = [] (* Number of songs *) let rec number_of_songs (pl : string list) : int = begin match pl with | [] -> 0 | x :: rest -> 1 + number_of_songs rest end let test () : bool = (number_of_songs pl1) = 4 ;; run_test "number_of_songs pl1" test let test () : bool = (number_of_songs pl2) = 3 ;; run_test "number_of_songs pl2" test let test () : bool = (number_of_songs pl3) = 0 ;; run_test "number_of_songs pl3" test let test () : bool = (number_of_songs gaga_songs) = 20 ;; run_test "number_of_songs gaga_songs" test (* Contains *) let rec contains (pl : string list) (song : string) : bool = begin match pl with | [] -> false | hd :: tl -> if song = hd then true else contains tl song end let test () : bool = (contains pl1 "Telephone") = true ;; run_test "contains pl1 Telephone" test let test () : bool = (contains pl2 "Telephone") = false ;; run_test "contains pl2 Telephone" test let test () : bool = (contains pl3 "Telephone") = false ;; run_test "contains pl3 Telephone" test let test () : bool = (contains gaga_songs "Telephone") = true ;; run_test "contains gaga_songs Telephone" test (* number of gaga_songs *) let rec number_of_gaga_songs (pl : string list) : int = begin match pl with | [] -> 0 | hd :: tl -> if contains gaga_songs hd then 1 + number_of_gaga_songs tl else number_of_gaga_songs tl end let test () : bool = (number_of_gaga_songs pl1) = 2 ;; run_test "number_of_gaga_songs pl1" test let test () : bool = (number_of_gaga_songs pl2) = 0 ;; run_test "number_of_gaga_songs pl2" test let test () : bool = (number_of_gaga_songs pl3) = 0 ;; run_test "number_of_gaga_songs pl3" test let test () : bool = (number_of_gaga_songs gaga_songs) = (number_of_songs gaga_songs) ;; run_test "number_of_gaga_songs gaga_songs" test (* all_gaga_songs *) let rec all_gaga_songs (pl : string list) : string list = begin match pl with | [] -> [] | hd :: tl -> if contains gaga_songs hd then hd :: all_gaga_songs tl else all_gaga_songs tl end let test () : bool = (all_gaga_songs pl1) = [ "Bad Romance"; "Telephone" ] ;; run_test "all_gaga_songs pl1" test let test () : bool = (all_gaga_songs pl2) = [] ;; run_test "all_gaga_songs pl2" test let test () : bool = (all_gaga_songs pl3) = [] ;; run_test "all_gaga_songs pl3" test let test () : bool = (all_gaga_songs gaga_songs) = gaga_songs ;; run_test "all_gaga_songs gaga_songs" test let rec all_non_gaga_songs (pl : string list) : string list = failwith "all_non_gaga_songs: unimplemented" let test () : bool = (all_non_gaga_songs pl1) = [ "Nightswimming"; "Everybody Hurts" ] ;; run_test "all_non_gaga_songs pl1" test let test () : bool = (all_non_gaga_songs pl2) = pl2 ;; run_test "all_non_gaga_songs pl2" test let test () : bool = (all_non_gaga_songs pl3) = [] ;; run_test "all_non_gaga_songs pl3" test let test () : bool = (all_non_gaga_songs gaga_songs) = [] ;; run_test "all_non_gaga_songs gaga_songs" test (* Function to convert a playlist to a string *) let rec string_of_playlist (pl : string list) : string = begin match pl with | [] -> "" | ( song :: rest ) -> "> " ^ song ^ "\n" ^ (string_of_playlist rest) end ;; print_endline "gaga.ml: no tests have failed."