12.07.2015 Views

Выпуск 14

Выпуск 14

Выпуск 14

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

СЕМИНАР40сентябрь 2011 / ИНФОРМАТИКАмного инфиксных чисел, и большая их часть пришлаиз мира математики. Основная масса функцийявляются префиксными, то есть их имена записываютсяперед аргументами, например, max 1 3.Заметьте особое отличие вызова функций в Haskellот вызовов в других языках — аргументы при записивызова пишутся без скобок и каких-либо разделительныхзнаков, поскольку все это имеет несколькодругой смысл.Разумеется, вы запросто можете определить собственныефункции. Вы должны разместить описаниефункции в файле с расширением *.hs и загрузитьэтот файл командой :l — определение функцийв командной строке интерпретатора работатьне будет (в дальнейшем будет описан способ сделатьэто, если уж очень хочется)! Опишем, к примеру,вышеупомянутую функцию doubleMe, котораяудваивает собственный аргумент. Это просто:doubleMe x = x + xили:doubleMe x = x * 2оба определения математически правильны и эквивалентны.Разумеется, вы можете определить другиефункции, используя уже определенные вамифункции (причем сделать это можно даже до определенияпоследних!):doubleMeTwice x = doubleMe (doubleMe x)Также вы можете использовать условные выраженияпри описании функций. Например, нам надоопределить функцию, которая будет удваиватьлишь числа не бÓльшие ста:doubleFromFirstHundred x = if x > 100then x else doubleMe xЗдесь необходимо заметить, что ветвь else вязыке Haskell обязательна по следующей причине:условный оператор является выражением, котороевсегда должно иметь определенное значение. Онни в коем случае не является чистой функцией, посколькузависит от значения переменных, определенныхвовне его, но он является полноправнымматематическим выражением.Константные выражения в Haskell тоже являютсяфункциями: функциями, не имеющими аргументови, следовательно (вспомните правило: чистаяфункция всегда должна давать один и тот же результатдля одних и тех же входных данных), имеющимиединственно возможное значение:temperature = 35Напоследок для людей, заинтересовавшихсяправилами именования функций: имя функциив Haskell не может начинаться с заглавной буквы,поэтому имена всех вышерассмотренных функцийначинаются со строчных букв. Кроме того, принятоеще одно интересное соглашение о наименованиифункций: имя функции, заканчивающееся на апостроф,обозначает либо неленивую функцию, либонесколько измененный вариант уже имеющейсяфункции. Такое именование — стандартная практикапри программировании на языке Haskell.Списки, списки, спискиСписок — одна из основных структур данных вязыке Haskell. Если вы имеете хоть малейший опытпрактического программирования, вы уже, вне сомнения,знаете, что такое список. В Haskell спискомможет быть однородное множество элементов. Выможете иметь список чисел или список символов,но не список, содержащий одновременно и числа исимволы. Например:ghci> let someList = [1, 2, 3, 4]ghci> let anotherList = ['h', 'e', 'l','l', 'o'][Замечание для любознательных читателей:слово let и есть та самая конструкция, котораяпозволяет определять функции прямо в строкеинтерпретатора (а ведь это определение спискаи есть определение функции, как я уже писалвыше). К сожалению, в Hugs это так просто несработает.]Строки являются частным случаем списков —это списки символов. Однако Haskell разрешает неписать каждый раз ['h', 'e', 'l', 'l', 'o'],когда мы хотим определить строку 'hello', вы можетезаписать ее напрямую.Одна из основных и простейших операцийнад списками — конкатенация, или склейка,списков:Hugs> [1, 2, 3, 4] ++ [9, 10, 11, 12][1, 2, 3, 4, 9, 10, 11, 12]Hugs> 'hello' ++ ' ' ++ 'world''hello world'Однако с частой конкатенацией очень длинныхсписков следует быть осторожным, поскольку этодовольно ресурсоемкая операция: при склейке двухсписков интерпретатор вынужден пройти первыйиз них от начала до конца, а, как нам известно, времяэтого прохода линейно зависит от числа элементовв списке.Теоретическая база списков в Haskell унаследованаиз языков семейства Лисп и заслуживает некоторогорассмотрения. Допустим, вы хотите добавитьэлемент в начало списка — это делается операторомдвоеточие:Hugs> 4:[1, 2, 3][4, 1, 2, 3]В данном случае число 4 называется головой списка,а список [1, 2, 3] — хвостом. Рассмотримсам список [1, 2, 3], его голова — 1, хвост —[2, 3]. Рассмотрим этот хвост, его голова — 2,хвост — [3]. Выражение [3] ни в коем случаене является числом, это список, имеющий голову3 и хвост [], где [] является специальным видомсписка — пустым списком. Таким образом,список [4, 1, 2, 3] имеет альтернативную(имеющую теоретически верный вид) форму4:1:2:3:[], однако при записи программ предпочтительноиспользовать первую форму записисписков для повышения читабельности.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!