Можно ли в sml свернуть элементы списка строк и вернуть другой список? - PullRequest
0 голосов
/ 02 октября 2018

Если нет, что мне делать, если я хочу одновременно изменить элементы в списке с помощью предопределенной функции и вернуть список в конце одной строкой кода?

Например: funupperClass - это предопределенная функция string -> string, которая делает все символы в строке верхним классом, и здесь у меня есть список ["a", "b", "c"]. Я хочу написать эту функцию не рекурсивно и используя foldrreturn ["Ä", "B", "C"].

Моя предыдущая попытка была foldr upperClass () [] ["a", "b", "c"], и получаетсянесоответствие типов, как и ожидалось, так как обычно я использую OP :: для помещения этих элементов обратно в список.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

То, что вы описываете, как вы сами комментируете, map:

val uppercase = String.map Char.toUpper
val uppercaseMany = List.map uppercase

Вы должны выбрать map, когда оно наиболее точно описывает то, что вы делаете, поскольку оно передает цель вашегокод быстрее.

map делает что-то более конкретное, чем foldl, поскольку map всегда может только возвращать список с тем же количеством элементов, что и его входные данные, где каждый элемент был преобразован точно втаким же образом и независимо от других функций (по крайней мере, в пределах собственной воли map).

Фактически, map является частным случаем foldr, поскольку вы можете реализовать map используя foldr, но не наоборот:

fun map f = foldr (fn (x, xs) => f x :: xs) []

foldl и foldr может свести список вещей к чему угодно, например к дереву:

datatype 'a binaryTree = Leaf | Branch of 'a * 'a binaryTree * 'a binaryTree
fun insert (x, Leaf) = Branch (x, Leaf, Leaf)
  | insert (x, Branch (y, left, right)) =
    if x <= y then Branch (y, insert (x, left), right)
              else Branch (y, left, insert (x, right))
val listToTree = foldl insert Leaf

Я выбрал foldl и foldr удобно, но вы также можете выразить одно с помощью другого .

Идея свертывания может работать с любой древовидной структурой, а не только со списками.Вот ответ StackOverflow на , как складывать бинарные деревья , и вот вопросы и ответы StackOverflow на Хвостовая рекурсия на деревьях .

0 голосов
/ 02 октября 2018

Давайте посмотрим на документацию foldl для list на http://sml -family.org / Basis / list.html # SIG: LIST.foldl: VAL

foldl f init [x1, x2, ..., xn]
   returns

   f(xn,...,f(x2, f(x1, init))...)

   or init if the list is empty. 

Как видите, конечный продукт foldl является продуктом функции f.Если тип возврата f является списком, вы можете получить список обратно.Поскольку вы упомянули, что вы пытались использовать ::, мы знаем, что этот оператор принимает два элемента: элемент типа 'a и список типа 'a и возвращает список типа 'a.foldl с использованием (op ::) также должен возвращать список.

Пример:

foldl (op ::) [] [1,2,3,4]

возвращает

val it = [4,3,2,1] : int list

Я думаю, что перед вами стоит задача придумать функцию f, которая возвращает список строк при обработкеэлементы одновременно.(Также в правильном порядке.)

...