Более подробно о ML
Джон Харрисон
Университет Кембриджа
10 сентября 2008 г.
Темы
Взаимодействие с ML
pythag 3 4 5 ; ;
p y t h a g 5 12 1 3 ; ;
pythag 1 2 3 ; ;
Комментарии
l e t pythag x y z =
x ∗ x + y ∗ y = z ∗ z ;;
( ∗ comments ∗ ) p y t h a g ( ∗ can ∗ ) 3 ( ∗ go ∗ ) 4
(∗ almost ∗) 5 (∗ anywhere ∗)
( ∗ and ( ∗ can ( ∗ be ( ∗ n e s t e d ∗ )
q u i t e ∗) a r b i t r a r i l y ∗) ∗) ; ;
Инфиксные операции
Оператор Значение
mod Modulus (остаток)
* Умножение
/ Целочисленное деление
+ Сложение
- Вычитание
^ Соединение строк
= Проверка равенства
<> Проверка неравенства
< Строго меньше
<= Меньше или равно
> Строго больше
>= Больше или равно
& Логическое «и»
or Логическое «или»
4
p&q = if p then q else false
4
p or q = if p then true else q
Примеры (1)
Мы определим рекурсивную функцию, которая принимает два
аргумента: положительное число n и функцию f , а возвращает f n ,
то есть f ◦ · · · ◦ f (n раз):
#l e t r e c funpow n f x =
i f n = 0 then x
e l s e funpow ( n − 1) f ( f x ) ; ;
funpow : i n t −> ( ’ a −> ’ a ) −>
’ a −> ’ a = <fun>
Примеры (2)
Сопоставление с образцом
Как и ожидалось у этой функции есть свойство, такое, что когда она
применяется к inl n, то возвращает n > 6, а когда применяется к
inr b, то возвращает b. Чем это обосновано?
Допускается восстановить n из inl n, потому что конструкторы
инъективны. Экземпляры образца не конфликтуют, потому что
конструкторы раздельны. В заключение, функция определена на
всех допустимых значениях, потому что конструкторы полны.
Неполное сопоставление
Повсеместное сопоставление
Мы можем производить сопоставление и в других ситуациях, когда
образцы не взаимно исключающие. В этом случае берётся первое
совпадение.
#(fun 0 −> t r u e | n −> f a l s e ) 0 ; ;
− : bool = true
#(fun 0 −> t r u e | n −> f a l s e ) 1 ; ;
− : bool = false
Рекурсивные типы
Как мы уже сказали, типы могут быть заданы рекурсивно, т.е. через
самих себя.
#type ( ’ a ) l i s t = N i l
| Cons o f ’ a ∗ ( ’ a ) l i s t ; ;
Type l i s t d e f i n e d .
#N i l ; ;
− : ’a l i s t = Nil
#Cons ; ;
− : ’ a ∗ ’ a l i s t −> ’ a l i s t = <fun>
Списки
Вообще то, такой тип уже является встроенным. Пустой список
записывается [], и у рекурсивного конструктора :: есть статус
инфиксной операции. Поэтому списки выше, в действительности,
записываются так:
#[];;
− : ’a l i s t = []
#1::[];;
− : int l i s t = [1]
#1::2::[];;
− : int l i s t = [ 1 ; 2]
#1::2::3::[];;
− : int l i s t = [ 1 ; 2; 3]