【问题标题】:SMLNJ if statement errorSMLNJ if 语句错误
【发布时间】:2013-07-22 19:18:23
【问题描述】:

我正在尝试学习 SML,并编写了一个类似于 Zed Shaw's book '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(功能)方式吗?

按照塞巴斯蒂安的回答:

只是为了通知普通读者:

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

【问题讨论】:

    标签: if-statement sml


    【解决方案1】:

    是什么原因造成的?

    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 表达式链,不如使用模式匹配,并分离出inputLine 返回的option 类型的处理,它可能会更简洁。我可能会这样写:

    (* 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"

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

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

    【讨论】:

    • 起初它在我看来像是一个字符串 - 选项类型错误。我试图通过打印来调试它,但没能抓住这个。在调试过程中我应该遵循什么一般规则才能检测到这种错误原因?你对强有什么建议吗? ly 类型的语言?
    • 就我个人而言,我倾向于通过程序,在某些程序点验证值是否符合我的预期(例如通过打印它们),从而缩小问题发生的范围。 :)
    猜你喜欢
    • 2017-04-28
    • 2011-09-22
    • 2017-05-04
    • 2017-05-29
    • 2014-06-20
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    相关资源
    最近更新 更多