0

我正在尝试学习 SML,并编写了一个类似于Zed Shaw 的“Learn Ruby The Hard Way”一书中的小游戏。下面的代码在 REPL 中运行良好,并且可以很好地与 MLTON 一起编译。但是,它总是导致 else 语句(“错误!”)。如果我尝试用print(valOf(response))if 语句代替它来调试它,它会返回我输入的任何字符串(如果我不输入任何内容,则返回一个空字符串)。所以我不认为是inputLine函数,也不是let语句不返回stdin,也不应该是比较操作。

fun first_room () =
    (print "You're in a dark, mottled room.\n";
     print "Which one do you choose? Left or Right?\n";
     print "> ";
     let val response = (TextIO.inputLine TextIO.stdIn)
     in
     if response = NONE
     then print "You stay.\n"
     else if valOf(response) = "Left"
     then print "You go left.\n"
     else if valOf(response) = "Right"
     then print "You go right.\n"
     else print "Error!\n"
     end)

fun main () = first_room ()
         
val _ = main ()

所以,我有两个问题: 1 - 什么可能导致这个?2 - 这是构建此程序程序的 ML(功能)方式吗?

按照塞巴斯蒂安的回答:

只是为了通知普通读者:

在寻找调试此错误的方法时,我注意到如果我输入TextIO.inputLine TextIO.stdIn;REPL 并输入一些 abc,我会得到“abc\n”。我不知道可以使用 REPL 来尝试 ML 程序而无需编译它们。

4

1 回答 1

0

什么可能导致这种情况?

的返回值TextIO.inputLine包括尾随换行符。也就是说,如果您编写Left并按下回车键,您实际上会得到作为值返回的字符串"Left\n"

为了解决这个问题,您可以制作一个简单的修剪功能,您可以使用它来删除该换行符。

(* trimLast : string -> string
   Trims off the last character in a string *)
fun trimLast s = String.substring(s, 0, size s - 1)

这是构建此程序程序的 ML(功能)方式吗?

如果您使用模式匹配if并分离出optioninputLine. 我可能会这样写:

(* trimLast : string -> string
 * Trims off the last character in a string *)
    fun trimLast s = String.substring(s, 0, size s - 1)

fun processInput f =
    case TextIO.inputLine TextIO.stdIn of
        NONE   => print "Goodbye.\n"
      | SOME s => f (trimLast s)

(* empty room functions, to make the program compile *)
fun leftRoom () = ()
fun rightRoom () = ()

fun firstRoom () = (
    print "You're in a dark, mottled room.\n";
    print "Which one do you choose? Left or Right?\n";
    print "> ";
    processInput (fn
        "Left"   => ( print "You go left.\n"; leftRoom () )
      | "Right"  => ( print "You go right.\n"; rightRoom () )
      | _        => ( print "You do nothing.\n"; firstRoom () )
    )
  )

请注意我是如何制作函数的processInput,它负责读取输入并处理选项值。例如,这还允许您在一个地方规范化输入,例如,如果您想将其小写,则可以同时处理"Left""left"

此外,我指定了将输入处理为函数的规则,该函数与给定的字符串匹配。

我会认为这种风格更实用、更干净。

于 2013-07-21T16:08:29.080 回答