(* Cat Huston - s0346906 *) (* Functional Programming and Specification - Practical 1, Exercise 1 *) fun inString letter s = (* takes a character and a string as an argument and returns whether the character is present in the string *) let fun inString' letter[] = false (* set to false so if the character isn't present in the string the function retuns false *) | inString' letter (y::ys) = (* the function checks the first character in the current string the calls itself recursively on the rest of the string *) if letter = y then true (* the character is present in the string *) else inString' letter ys in inString' letter (explode s) (* splits the string into a list of characters *) end; fun getCode letter = (* takes a character as an argument and returns a code *) if inString (Char.toLower letter) "aehiouwy" then #"0" (* the character will be removed *) else if inString (Char.toLower letter) "bfpv" then #"1" else if inString (Char.toLower letter) "cgjkqsxz" then #"2" else if inString (Char.toLower letter) "dt" then #"3" else if (Char.toLower letter) = #"l" then #"4" else if inString (Char.toLower letter) "mn" then #"5" else if (Char.toLower letter) = #"r" then #"6" else #"0"; (* the character is not a letter and will be removed *) fun dropReps[] = [] (* drops the repeated characters from the string *) | dropReps [x] = [x] | dropReps (x::y::st) = (* the function checks the first two characters in the string then calls itself on the second character and the rest of the string *) if getCode x = getCode y then dropReps(x::st) (* drops y and resplits the string *) else x:: dropReps(y::st) (* retains the y and resplits the string with the y *) fun dropChars[] = [] (* drops the characters with code zero from the string *) | dropChars (x::xs) = (* the function checks the first character in the string then calls itself on the rest of the string *) if getCode x = #"0" then dropChars xs (* drops the character and splits the string *) else x:: dropChars xs (* retains the character and splits the string *) fun codeSt[] = [] (* takes a list of characters and returns a list of the codes *) | codeSt (x::st) = getCode x :: codeSt st fun take 0 _ = [] (* takes a list of characters and returns a list of length 4 *) | take n [] = #"0" :: take (n-1) [] | take n (x::xs) = x :: take (n-1) xs fun soundex st = (* main function *) let val (c::cs) = dropReps (explode st) in implode (c :: take 3 (codeSt (dropChars cs))) end;