我有一个字符列表[#"h", #"i", #" ", #"h", #"i"]
,我希望从中得到第一个字(每个空格前的第一个字符序列)。
我写了一个函数,它给了我这个警告:
stdIn:13.1-13.42警告:因价值而未输入广义类型 限制被实例化为虚拟类型(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"])
有人可以帮我解决这个问题吗?谢谢!
答案 0 :(得分:1)
此功能已存在于标准库中:
val nexts = String.tokens Char.isSpace
val nexts_test = nexts "hi hi hi" = ["hi", "hi", "hi"]
但是如果你要构建这样一个函数,似乎有时会返回([], [])
,有时会返回一个列表。通常在递归函数中,您可以通过执行以下操作来构建结果: c :: recursive_f cs
,但这假设您的函数返回单个列表。相反,如果它返回一个元组,你突然必须使用例如解压缩这个元组。 let-expression中的模式匹配:
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 [] = ([], [])