2015-10-25 47 views
0

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

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

标准输入: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"]) 

任何人可以帮助我解决?谢谢!

回答

1

这个功能已经在标准库中存在:

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

但是如果你无论如何要建立这样一个功能,看来你有时会返回([], [])并在其他时间一个列表。通常在递归函数中,您可以通过执行c :: recursive_f cs,但这是假设你的函数返回一个列表。相反,如果它返回一个元组,你就必须用这个元组来打开这个元组。模式在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 [] = ([], []) 
+0

目标是不使用常见的ML函数,我们必须递归地完成整个事情。 但是你的建议真的很好!谢谢 – madcrazydrumma

相关问题