Что касается первого, это очень простой способ рекурсии. Тем не менее, кажется, что отсутствует часть:
myLength [] = 0
Он работает, вычеркивая один элемент за раз из списка и добавляя один к результату. Для визуализации рассмотрим звонок
myLength [1,2,3]
, который будет оценивать:
1 + myLength [2,3]
1 + 1 + myLength [3]
1 + 1 + 1 + myLength []
1 + 1 + 1 + 0
, что составляет 3.
Что касается второго, ну, вы уже разбили строку на следующем разрыве строки на две части: pre и suf. Теперь suf будет начинаться либо с \ n, либо с \ r, либо с \ r \ n. Мы хотим удалить это. Поэтому мы используем сопоставление с образцом. Посмотрите, как переменная rest является по существу переменной suf минус начальный символ (ы) разрыва строки.
Итак, у нас есть pre, первая строка, и rest, остальная часть текста. Поэтому, чтобы продолжить разбиение остатка на строки, мы рекурсивно вызываем для него splitLines и объединяем результат с pre.
Для визуализации, скажем, у вас есть строка "foo \ nbar \ r \ nbaz".
Итак, при звонке результат будет:
[ pre => foo, suf => \nbar\r\nbaz, rest => bar\r\n\baz ]
foo : splitLines bar\r\nbaz
затем вызывается splitLines, и результат расширяется до:
[ pre => bar, suf => \r\nbaz, rest = baz ]
foo : bar : splitLines baz
затем еще раз:
[ pre => baz, suf => [], rest = [] ]
foo : bar : baz
что является окончательным результатом.