Функция SMLNJ, которая возвращает в виде пары строку в начале списка - PullRequest
0 голосов
/ 13 июля 2020

Так что я действительно запутался, так как я новичок в sml, и у меня проблемы с синтаксисом того, как я хочу создать свою функцию.

инструкции следующие ...

numberPrefix : список символов → строка * список символов

Напишите функцию с именем numberPrefix, которая возвращает (в виде пары) строку, представляющую символы di git в начале списка ввода и оставшиеся символы после этого префикса. Вы можете использовать в своей реализации функции Char.isDi git и String.implode. Например,

  • numberPrefix [# "a", # "2", # "c", # "", # "a"];

val it = ("", [# "a", # "2", # "c", # "", # "a"): строка * список символов

  • numberPrefix [ # "2", # "3", # "", # "a"];

val it = ("23", [# "", # "a"]): string * список символов

Вот мой код до сих пор ...

fun numberPrefix(c:char list):string*char list =
case c of
[] => []
|(first::rest) => if isDigit first
                  then  first::numberPrefix(rest)
                  else  

;

Я думаю, что я пытаюсь сначала добавить в отдельный список, если это действительно di git, как только я достигну члена списка char, я хотел бы вернуть этот список с помощью String.implode, но я бью головой об идее передать вспомогательную функцию или даже просто использовать выражение «пусть». Как я могу создать отдельный список, одновременно отслеживая, где я нахожусь в исходном списке, чтобы я мог вернуть результат в правильном формате?

1 Ответ

0 голосов
/ 14 июля 2020

Прежде всего, функция должна создавать пару, а не список. Базовый случай должен быть ("", []), а не [], и вы не можете передать рекурсивный результат "нетронутым". (Вы можете в значительной степени отличить это только по типам. Обратите внимание на типы; они хотят вам помочь.)

Если вы привяжете результат рекурсии к let, вы можете получить доступ к его частям отдельно и переставьте их. Прямая рекурсивная попытка может выглядеть так:

fun numberPrefix [] = ("", [])
  | numberPrefix (cs as (x::xs)) = 
        if Char.isDigit x
        then let val (number, rest) = numberPrefix xs 
             in
                 ((str x) ^ number, rest)
             end
        else ("", cs);

Однако разделение списка на два на основе предиката - назовем его «splitOn» с типом ('a -> bool) -> 'a list -> 'a list * 'a list - довольно полезная операция, и если бы у вас была эта функция, вам нужно было бы только что-то вроде этого:

fun numberPrefix xs = let val (nums, notnums) = splitOn Char.isDigit xs
                      in
                          (String.implode nums, notnums)
                      end;

(Разделение слева в качестве упражнения. Я подозреваю, что вы уже реализовали эту функцию разделения или ее близкие родственники "takeWhile" и " dropWhile ".)

...