2014-01-07 40 views
0

枚舉類型的數據:OCaml的 - 通過標準輸入標準輸出輸入,顯示,驗證枚舉類型

type sex = | M | F | Undef;; 

我不知道什麼是首選「OCaml的」方式在控制檯程序進入和驗證枚舉類型的數據?我試着編寫下面的程序,我確定我正確地顯示了枚舉類型,但我不確定while循環中的驗證是否正確。基本上我希望while循環內容提示用戶輸入枚舉類型的有效數據,並顯示輸入的值,然後退出循環或失敗,並重新提示用戶輸入有效數據。

type sex = | M | F | Undef;; 
type loop = | Yes | No;; 

let match_sex s str = 
    match s with 
    | M -> print_endline "Male" 
    | F -> print_endline "Female" 
    | Undef -> 
      Printf.fprintf stdout "You entered '%s'. Please enter single character(M\\F)\n" str;; 

let looping = ref Yes;; 

while !looping = Yes do 
    let s = looping := No; print_string "Enter sex(M\\F)->"; read_line() in 
    let c = Char.uppercase s.[0] in 
    let ans = 
     match (c, String.length s) with 
     | 'M', 1 -> M 
     | 'F', 1 -> F 
     | _ -> looping := Yes; Undef in match_sex ans s 
done;; 

在此先感謝您的任何意見或建議。

回答

1

個人而言,我只希望做

type sex = M | F 

let rec prompt() = 
    let input = 
    print_string "Enter sex(M\\F)->"; 
    read_line() in 
    match String.uppercase input with 
    | "M" -> print_endline "Male"; M 
    | "F" -> print_endline "Female"; F 
    | bad_input -> 
    Printf.printf "You entered '%s'. Please enter single character(M\\F)\n" bad_input; 
    prompt() 

的幾點:

  • 喜歡遞歸循環上
  • 額外的功能不買你在這裏多,所以我擺脫它
  • 我刪除了Undef性別,因爲它永遠不會被退回。
  • Printf.printf超過Printf.fprintf stdout
+0

好吧,我看你做了什麼,爲什麼你做到了。我想我很難擺脫我的命令式編程特徵,並以功能性的方式思考。感謝您的時間和指導。 – G4143

0
type sex = | Male | Female;; 

let match_sex sx = 
    match sx with 
    | Male -> "Male" 
    | Female -> "Female";; 

let rec get_sex() = 
    let str = print_string "Enter sex(M/F)->"; read_line() in 
    match Char.uppercase (str.[0]), String.length str with 
    | 'M', 1 -> Male 
    | 'F', 1 -> Female 
    | undef_sex -> 
      Printf.fprintf stdout "Your entry '%s' was invalid. Please try again.\n" str; get_sex();; 

Printf.fprintf stdout "Your sex is->%s\n" (match_sex (get_sex()));; 

這是我最後與去解決。謝謝rgrinberg