首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SMLNJ if语句错误

SMLNJ if语句错误
EN

Stack Overflow用户
提问于 2013-07-21 22:50:50
回答 1查看 157关注 0票数 0

我正在努力学习SML,并写了一个类似于Zed Shaw's book 'Learn Ruby The Hard Way'.的小游戏,下面的代码在REPL中运行良好,并且与MLTON编译得很好。但是,它总是导致else语句("Error!")。如果我尝试用print(valOf(response))来调试它,而不是If语句,它将返回我键入的任何字符串(如果我没有键入任何内容,则返回一个空字符串)。所以我认为它不是inputLine函数,也不是let语句不返回stdin,也不应该是比较op。

代码语言:javascript
运行
复制
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 (函数式)方法吗?

以下是Sebastian的回答:

我只想告诉普通读者:

在寻找调试此错误的方法时,我注意到如果我在REPL中键入TextIO.inputLine TextIO.stdIn;,然后键入一些abc,我得到的结果是"abc\n“。我不知道人们可以使用REPL来尝试ML程序而不编译它们。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-22 00:08:29

什么可能会导致这种情况?

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

为了解决这个问题,你可以创建一个简单的修剪函数,你可以用它来删除换行符。

代码语言:javascript
运行
复制
(* trimLast : string -> string
   Trims off the last character in a string *)
fun trimLast s = String.substring(s, 0, size s - 1)

这是构建这个过程程序的ML (函数式)方式吗?

如果使用模式匹配,并分离inputLine返回的option类型的处理,而不是编写if-expressions链,可能会更简洁。我可能会这样写:

代码语言:javascript
运行
复制
(* 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"

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

我认为这种风格更实用、更整洁。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17773592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档