试图从字符列表中获取第一个单词
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 [] = ([], [])
我有一个字符列表 [#"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 [] = ([], [])