【问题标题】:SMLNJ function that returns as a pair a string at the beginning of a listSMLNJ 函数以对形式返回列表开头的字符串
【发布时间】:2020-11-02 06:31:24
【问题描述】:

所以我真的很困惑,因为我是 sml 的新手,而且我在创建函数的语法方面遇到了问题。

说明如下……

numberPrefix: 字符列表 → 字符串 * 字符列表

编写一个名为 numberPrefix 的函数,它返回(成对)一个字符串,该字符串表示在 输入列表的开头和此前缀之后的剩余字符。您可以使用 Char.isDigit 和 实现中的 String.implode 函数。 例如,

  • 数字前缀 [#"a", #"2", #"c", #" ", #"a"];

val it = ("", [#"a", #"2", #"c", #" ", #"a") : 字符串 * 字符列表

  • 数字前缀 [#"2", #"3", #" ", #"a"];

val it = ("23", [#" ", #"a"]) : 字符串 * 字符列表

到目前为止,这是我的代码...

fun numberPrefix(c:char list):string*char list =
case c of
[] => []
|(first::rest) => if isDigit first
                  then  first::numberPrefix(rest)
                  else  

;

我想我想要做的是首先附加到一个单独的列表,如果它确实是一个数字,一旦我到达 char 列表的成员,然后我想使用 String.implode 返回该列表,但我是对传递辅助函数甚至只使用“let”表达式的想法猛烈抨击。如何在本质上创建一个单独的列表,同时跟踪我在原始列表中的位置,以便我可以以正确的格式返回结果?

【问题讨论】:

    标签: sml ssml


    【解决方案1】:

    首先,函数应该产生一对,而不是列表。
    基本情况应该是("", []),而不是[],并且您不能将递归结果传递给“未触及”。
    (你几乎可以从类型中看出这一点。注意类型;他们想帮助你。)

    如果您将递归结果绑定到let,您可以单独访问其部分并重新排列它们。
    直接递归的取值可能如下所示:

    fun numberPrefix [] = ("", [])
      | numberPrefix (cs as (x::xs)) = 
            if Char.isDigit x
            then let val (number, rest) = numberPrefix xs 
                 in
                     ((str x) ^ number, rest)
                 end
            else ("", cs);
    

    然而,基于谓词将列表一分为二——我们称之为“splitOn”,类型为('a -> bool) -> 'a list -> 'a list * 'a list——是一个相当有用的操作,如果你有这个功能,你只需要这样的东西:

    fun numberPrefix xs = let val (nums, notnums) = splitOn Char.isDigit xs
                          in
                              (String.implode nums, notnums)
                          end;
    

    (左分割作为练习。我怀疑你已经实现了这个分割功能,或者它的近亲“takeWhile”和“dropWhile”。)

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 2016-10-19
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-17
      • 1970-01-01
      • 2011-03-04
      相关资源
      最近更新 更多