试图从字符列表中获取第一个单词

Trying to get first word from character list

我有一个字符列表 [#"h", #"i", #" ", #"h", #"i"],我想从中获取第一个单词(每个 space 之前的第一个字符序列)。

我写了一个函数,它给我这个警告:

stdIn:13.1-13.42 Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...)

这是我的代码:

fun next [] = ([], [])
   | next (hd::tl) = if(not(ord(hd) >= 97 andalso ord(hd) <= 122)) then ([], (hd::tl))
       else
         let
           fun getword [] = [] | getword (hd::tl) = if(ord(hd) >= 97 andalso ord(hd) <= 122) then [hd]@getword tl else [];
         in
           next (getword (hd::tl))
         end;

编辑:

预期输入输出

next [#"h", #"i", #" ", #"h", #"i"] => ([#"h", #"i"], [#" ", #"h", #"i"]) 

有人可以帮我解决这个问题吗?谢谢!

此功能已存在于标准库中:

val nexts = String.tokens Char.isSpace
val nexts_test = nexts "hi hi   hi" = ["hi", "hi", "hi"]

但是,如果您无论如何要构建这样一个函数,似乎您有时 return ([], []) 有时是一个列表。通常在递归函数中,您可以通过执行例如构建结果c :: recursive_f cs,但这是假设您的函数 return 是一个列表。相反,如果它 return 是一个元组,你突然不得不使用例如解压这个元组let 表达式中的模式匹配:

let val (x, y) = recursive_f cs
in (c :: x, y + ...) end

或者您可以在辅助函数中使用一个额外的参数(因为额外的参数会改变函数的类型)来存储您正在提取的单词。这样做的结果是你最终得到的是反向的单词,当你完成递归时必须将它反向。

fun isLegal c = ord c >= 97 andalso ord c <= 122  (* Only lowercase ASCII letters *)
(* But why not use one of the following:
   fun isLegal c = Char.isAlpha c
   fun isLegal c = not (Char.isSpace c)  *)

fun next input =
    let fun extract (c::cs) word =
              if isLegal c
              then extract cs (c::word)
              else (rev word, c::cs)
          | extract [] word = (rev word, [])
    in extract input [] end

val next_test_1 =
    let val (w, r) = next (explode "hello world")
    in (implode w, implode r) = ("hello", " world")
    end

val next_test_2 = next [] = ([], [])