我目前正在学习SML函数式语言,我正在尝试创建一个带有字符列表的函数,然后当它找到一个空白区域时,它会在列表中搜索任何空格,然后在白色空格之前将字符连接起来之后的字符串,它返回由白色空格分隔的字符组成的字符串列表。
这是我的代码,但编译器说在eof上有错误,它有问题!
fun sepWords ([]) = []
| sepWords (x :: xs) =
let
val word = ""
val list
sepWords (xs)
in
if (Char.isSpace (x)) then (word = "")
else (word ^ x)
word :: list
end;
答案 0 :(得分:1)
您在val list
行和sepWords (xs)
行周围出现语法错误。也许你打算写val list = sepWords (xs)
?您还会在if ...
和word :: list
行周围出现语法错误。我不确定这里的意图是什么,但也许您认为word :: list
会产生添加'字'的副作用。到'列出'?
您的if ...
中存在类型错误,因为'然后' branch的表达式word = ""
具有类型 bool 和' else' branch的表达式word ^ x
的类型为 string 。 if-then-else必须在每个分支上具有相同的类型,以便类型检查器接受该程序。
而不是使用 char list - &gt;类型创建函数字符串列表,为什么不创建类型为 string - &gt;的函数字符串列表?如果这样做,您甚至可以通过将字符索引跟踪到原始字符串中来避免将字符串转换为字符列表的中间步骤(例如,通过使用< em> substring type)。
该功能的一个好名字可能是&#39;单词&#39;
您尚未定义连续发生多个空格的行为。 words "hello world"
应该生成["hello", "world"]
还是["hello", "", "world"]
?
实际上有内置的库函数可以执行此操作:
- String.tokens Char.isSpace "hello world";
> val it = ["hello", "world"] : string list
- String.fields Char.isSpace "hello world";
> val it = ["hello", "", "world"] : string list
首先将字符串转换为字符列表的替代方法是列表递归中的一个很好的练习,即使策略不是非常有效。您可以通过解决从输入中提取单个单词以及字符串的其余部分来解决此问题:
fun firstWord [] = ([], [])
| firstWord (c::cs) =
if Char.isSpace c
then ([], cs) (* throw away the space c *)
else case firstWord cs of
(fw, remainder) => (c::fw, remainder)
你可以这样称呼:
- firstWord (explode "hello world");
> val it =
([#"h", #"e", #"l", #"l", #"o"], [#" ", #"w", #"o", #"r", #"l", #"d"])
: char list * char list
只要余数不为空,你就可以递归调用它:
fun words [] = []
| words cs =
let val (fw, remainder) = firstWord cs
in implode fw :: words remainder end
使用这个:
- allWords (explode "hello world");
> val it = ["hello", "", "world"] : string list