2014-10-30 1 views
0

Я нашел этот кусок кода по вопросу, который похож на тот, который я пытаюсь решить, и я пытаюсь применить логику этой функции к своей проблеме , Однако объяснение кода не совсем понятно по этому вопросу. Код выглядит следующим образом:Разбиение списка на кортеж списков по указанному индексу

splitAtIndex :: Int -> [a] -> ([a], [a]) 
    splitAtIndex 0 xs = ([], xs) 
    splitAtIndex _ [] = ([], []) 
    splitAtIndex x (y:ys) = (y:ys', ys'') 
    where 
     (ys', ys'') = splitAtIndex (x - 1) ys 

, как я понимаю, что вы принимаете индекс и весь список и сформировать кортеж списков, где кортеж списков равно рекурсивного вызова индекса-1 хвоста списка. Я что-то упустил? Здесь важно использование апострофов? Я действительно не вижу, где происходит разделение списка. Я уверен, что однажды объяснил, что это будет просто, но я не могу понять этого.

Спасибо!

+1

Апострофы только как буквы в этом контексте. 'Ys'' является обычным идентификатором. Это может быть любой другой идентификатор. Используйте' xyzzy123 'или что-то еще. Не совсем ясно, каковы ваши другие трудности.« Где «раскол»? Вся эта функция «где». Новые списки создаются постепенно. Если вы ожидаете, что исходный список будет разрушен какое-то место, то нет, этого не происходит в Haskell. –

+0

Я предполагаю, что то, о чем я прошу, является пошаговым объяснением того, что происходит для выполнения разделения, извините за то, что он не ясен. – Bradley

+0

Функция (1) определяет как разбить список на некоторый индекс с точки зрения разделения меньшего списка на меньший индекс, а pr ovides два особых случая: (2) разбиение списка на индекс 0 и (3) разделение пустого списка.Давайте поговорим о (1). Можете ли вы объяснить на простом английском языке, не глядя в код, как разбить список, предполагая, что вы уже знаете, как разбить меньший список? –

ответ

0

Апоптопы относятся к переменным, которые используются для рекурсивного вызова splitAtIndex (x - 1) ys. Это единственный смысл.

И вы можете понять код, когда начинаете в своих мыслях с помощью индекса 1. Здесь вы берете пустой список слева от кортежа и висете слева от него. И так далее.

1

Как указывалось, апострофы эквивалентны буквам в именах. Соглашением является то, что если у вас есть переменная x, тогда измененная копия x часто называется x'.

Чтобы устранить эту путаницу, вы могли бы переписать определение как:

splitAtIndex x (y:ys) = (y:p, q) where (p, q) = splitAtIndex (x - 1) ys

Чтобы понять алгоритм, это может быть полезно рассмотреть пример. Допустим, вы хотите разделить список [1,2,3,4,5,6] в позиции 2. Вызов будет:

splitAtIndex 2 [1,2,3,4,5,6]

Предложение where в результатах функции в следующем выражение:

splitAtIndex 1 [2,3,4,5,6]

, потому что ys есть хвост и (x-1) представляет собой (2-1). Результатом этого выражения является кортеж (p,q). Но результат оригинального выражения переносит первый элемент исходного списка на первый элемент кортежа (y:p,q). Поэтому результатом splitAtIndex 2 [1,2,3,4,5,6] является (1:p, q), где p является первым элементом splitAtIndex 1 [2,3,4,5,6] и q является вторым элементом этого кортежа. Как и следовало ожидать splitAtIndex 1 [2,3,4,5,6] вернуть ([2],[3,4,5,6]), конечный результат (1:[2],[3,4,5,6]) (который ([1,2],[3,4,5,6]).