Эта статья включает в себя список общих ссылок , но он остается в значительной степени непроверенным, поскольку в нем отсутствует достаточное количество соответствующих встроенных ссылок . ( Сентябрь 2016 г. ) ( Узнайте, как и когда удалить этот шаблон сообщения ) |
Парадигма | ленивый , функциональный , декларативный |
---|---|
Разработано | Дэвид Тернер |
Разработчик | Research Software Ltd |
Впервые появился | 1985 г. |
Печатная дисциплина | сильный , статичный |
Веб-сайт | miranda |
Основные реализации | |
Миранда | |
Под влиянием | |
KRC , ML , SASL , Надежда | |
Под влиянием | |
Чистый , Хаскелл , Оруэлл , Microsoft Power Fx |
Miranda - это ленивый , чисто функциональный язык программирования, разработанный Дэвидом Тернером в качестве преемника его более ранних языков программирования SASL и KRC , с использованием некоторых концепций ML и Hope . Он был разработан английской компанией Research Software Ltd. (владеющей торговой маркой Miranda ) и стал первым чисто функциональным языком, получившим коммерческую поддержку. [ необходима цитата ]
Miranda была впервые выпущена в 1985 году как быстрый интерпретатор C для операционных систем со вкусом Unix , с последующими выпусками в 1987 и 1989 годах. Miranda оказала сильное влияние на более поздний язык программирования Haskell . [1]
Обзор [ править ]
Миранда - ленивый , чисто функциональный язык программирования. То есть в нем отсутствуют побочные эффекты и функции обязательного программирования . Программа Miranda (называемая скриптом ) - это набор уравнений, которые определяют различные математические функции и алгебраические типы данных . Здесь важен набор слов : порядок уравнений, как правило, не имеет значения, и нет необходимости определять объект до его использования.
Поскольку алгоритм синтаксического анализа интеллектуально использует макет (отступ), редко требуется заключать в скобки операторы и не требуются терминаторы операторов. Эта функция, вдохновленная ISWIM , также используется в occam и Haskell, а позже была популяризирована Python .
Комментарий вводится персонажами в обычный сценарий ||
и продолжается до конца той же строки. Альтернативное соглашение о комментировании влияет на весь файл исходного кода, известное как « грамотный сценарий », в котором каждая строка считается комментарием, если она не начинается со >
знака.
Основные Миранды типы данных являются char
, num
и bool
. Символьная строка - это просто список char
, num
который незаметно преобразуется между двумя базовыми формами: целыми числами произвольной точности (также известными как bignums) по умолчанию и обычными значениями с плавающей запятой по мере необходимости.
Кортежи - это последовательности элементов потенциально смешанных типов, аналогичные записям в языках, подобных Pascal , и записываются в скобках:
this_employee = ( "Фолланд, Мэри" , 10560 , Ложь , 35 )
Список вместо наиболее часто используется структура данных в Миранде. Он пишется в квадратных скобках и с элементами, разделенными запятыми, и все они должны быть одного типа:
week_days = [ "ПН" , "ВТ" , "ср" , "ЧГ" , "ПТ" ]
Объединение списков ++
, вычитание --
, построение :
, размер #
и индексация !
, поэтому:
days = week_days ++ [ «сб» , «вс» ] days = "Nil" : дней дней ! 0 ⇒ «Ноль» days = days - [ "Nil" ] # дней ⇒ 7
Существует несколько ярлыков для создания ..
списков : используется для списков, элементы которых образуют арифметический ряд, с возможностью указания приращения, отличного от 1:
fac n = продукт [ 1 .. n ] odd_sum = sum [ 1 , 3 .. 100 ]
Более общие и мощные средства построения списков предоставляются « списками » (ранее известными как «выражения ZF»), которые бывают двух основных форм: выражение, применяемое к ряду терминов, например:
квадраты = [ n * n | п <- [ 1 .. ] ]
(который читается: список n в квадрате, где n берется из списка всех положительных целых чисел) и ряд, в котором каждый член является функцией предыдущего, например:
powers_of_2 = [ n | п <- 1 , 2 * п .. ]
Как следует из этих двух примеров, Миранда допускает списки с бесконечным числом элементов, самый простой из которых - это список всех положительных целых чисел: [1..]
Обозначения для применения функции просто сопоставлены, как в sin x
.
В Миранде, как и в большинстве других чисто функциональных языков, функции являются первоклассными гражданами, то есть они могут быть переданы в качестве аргументов другим функциям, возвращены как результаты или включены как элементы структур данных. Более того, функция с двумя или более параметрами может быть «частично параметризована» или каррирована путем предоставления меньшего количества аргументов, чем полное количество параметров. Это дает другую функцию, которая, учитывая оставшиеся параметры, вернет результат. Например:
добавить a b = a + b приращение = добавить 1
- это обходной способ создания функции «приращение», которая добавляет единицу к своему аргументу. На самом деле, add 4 7
принимает двухпараметрическую функцию add
, применяет ее к 4
получению однопараметрической функции, которая добавляет четыре к своему аргументу, а затем применяет это к 7
.
Любую функцию с двумя параметрами (операндами) можно превратить в инфиксный оператор (например, с учетом определения add
функции, приведенной выше, этот термин $add
во всех отношениях эквивалентен +
оператору), и каждый инфиксный оператор, принимающий два параметра, может быть превращен в соответствующая функция. Таким образом:
приращение = ( + ) 1
- это кратчайший способ создать функцию, добавляющую единицу к своему аргументу. Точно так же в
половина = ( / 2 ) обратная = ( 1 / )
генерируются две однопараметрические функции. Интерпретатор понимает в каждом случае, какой из двух параметров оператора деления предоставляется, давая функции, которые соответственно делят число на два и возвращают его обратное.
Хотя Miranda является языком программирования со строгой типизацией , он не требует явного объявления типов . Если тип функции не объявлен явно, интерпретатор делает вывод из типа ее параметров и того, как они используются в функции. В дополнении к основным типам ( char
, num
, bool
), она включает в себя типа «ничего» , где тип параметра не имеет значения, как и в функции списка реверсирования:
rev [] = [] rev ( a : x ) = rev x ++ [ a ]
который может быть применен к списку любого типа данных, для которого явное объявление типа функции будет:
rev :: [ * ] -> [ * ]
Наконец, он имеет механизмы для создания программных модулей и управления ими , внутренние функции которых невидимы для программ, вызывающих эти модули.
Пример кода [ править ]
Следующий скрипт Миранды определяет набор всех подмножеств набора чисел.
подмножества [] = [ [] ] подмножества ( x : xs ) = [[ x ] ++ y | y <- ys ] ++ ys, где ys = подмножества xs
и это грамотный сценарий для функции, primes
которая дает список всех простых чисел
> || Бесконечный список всех простых чисел.Список потенциальных простых чисел начинается с целых чисел от 2 и выше; когда возвращается каждое простое число, все следующие числа, которые можно точно разделить на него, отфильтровываются из списка кандидатов.> простые числа = решето [2 ..] > решето (p: x) = p: решето [n | п <- х; n mod p ~ = 0]
Здесь у нас есть еще несколько примеров
max2 :: num -> num -> num max2 a b = a , если a > b = b , иначеmax3 :: num -> num -> num -> num max3 a b c = max2 ( max2 a b ) ( max2 a c )multiply :: num -> num -> num multiply 0 b = 0 multiply a b = b + ( multiply ( a - 1 ) b )fak :: num -> num fak 0 = 1 fak n = n * ( фак n - 1 )itemnumber :: [ * ] -> num itemnumber [] = 0 itemnumber ( a : x ) = 1 + itemnumber xбудний день :: = Пн | Вт | Мы | Чт | Пт | Sa | ВсisWorkDay :: будний день -> bool isWorkDay Sa = False isWorkDay Su = False isWorkDay anyday = Trueдерево * :: = E | N ( дерево * ) * ( дерево * )nodecount :: tree * -> num nodecount E = 0 nodecount ( N l w r ) = nodecount l + 1 + nodecount remptycount :: tree * -> num emptycount E = 1 emptycount ( N l w r ) = emptycount l + emptycount rtreeExample = N ( N ( N E 1 E ) 3 ( N E 4 E )) 5 ( N ( N E 6 E ) 8 ( N E 9 E )) день недели Дерево = N ( N ( N E Mo E ) Tu ( N E We E )) Th ( N ( N E Fr E ) Sa ( N E Su ))insert :: * -> stree * -> stree * insert x E = N E x E insert x ( N l w E ) = N l w x insert x ( N E w r ) = N x w r вставка x ( N l w r ) = вставить x l , если x < w = insert x r , иначеlist2searchtree :: [ * ] -> дерево * list2searchtree [] = E list2searchtree [ x ] = N E x E list2searchtree ( x : xs ) = insert x ( list2searchtree xs )maxel :: tree * -> * maxel E = ошибка "пустой" maxel ( N l w E ) = w maxel ( N l w r ) = maxel rminel :: tree * -> * minel E = ошибка "пустой" minel ( N E w r ) = w minel ( N l w r ) = minel l|| Пересекая: происходит через значений из дерева , помещая их в списокпредпорядок , Симметричный , postorder :: дерево * -> [ * ] Симметричный E = [] Симметричный N л ш г = Симметричный л ++ [ ш ] ++ Симметричного гпредзаказ E = [] предзаказ N l w r = [ w ] ++ предзаказ l ++ предзаказ rpostorder E = [] postorder N l w r = postorder l ++ postorder r ++ [ w ]height :: tree * -> num height E = 0 height ( N l w r ) = 1 + max2 ( высота l ) ( высота r )amount :: num -> num amount x = x , если x > = 0 amount x = x * ( - 1 ), в противном случаеand :: bool -> bool -> bool и True True = True и x y = False|| AVL - Дерево является деревом , где разница между в дочерних узлах является не более чем 1 || я до сих пор есть , чтобы проверить это isAvl :: tree * -> bool isAvl E = True isAvl ( N l w r ) = и ( isAvl l ) ( isAvl r ), если amount (( nodecount l ) - ( nodecount r )) < 2 = False , в противном случае delete :: * -> tree * -> tree * delete x E = E delete x ( N E x E ) = E delete x ( N E x r ) = N E ( minel r ) ( delete ( minel r ) r ) удалить x ( N l x r ) = N (delete ( maxel l ) l ) ( maxel l ) r delete x ( N l w r ) = N ( удалить x l ) w ( удалить x r )
Ссылки [ править ]
- ^ Худак, Пол; Хьюз, Джон (2007). «История Haskell: лень с классом» .
Внешние ссылки [ править ]
- Официальный веб-сайт