2015-10-25 1 views
0

У меня есть список символов [#"h", #"i", #" ", #"h", #"i"], который я хочу получить из этого первого слова (первая последовательность символов перед каждым пространством).Попытка получить первое слово из списка символов

Я написал функцию, которая дает мне это предупреждение:

STDIN: 13.1-13.42 Внимание: тип VARS не обобщенному из значения ограничений инстанцируется для фиктивных типов (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; 

EDIT:

Ожидаемый ввод и вывод

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

 Смежные вопросы

  • Нет связанных вопросов^_^