1 / 21

типы и классы

Лекция. типы и классы. Пользовательские типы. Для задания пользовательских типов служит ключевое слово data . Объявим тип Point - точка на плоскости. Если понимать точку как два вещественных числа, то определение типа будет таким. data Point = Point Double Double

diamond
Télécharger la présentation

типы и классы

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Лекция типы и классы

  2. Пользовательские типы Для задания пользовательских типов служит ключевое слово data. Объявим тип Point- точка на плоскости. Если понимать точку как два вещественных числа, то определение типа будет таким. data Point = Point Double Double data– ключевое слово. Point – имя типа, пишется с большой буквы. Point Double Double– конструктор, создает точку из двух чисел. Первое слово конструктора – метка.

  3. Именованные поля Тип можно объявить так, что отдельные части его значения будут иметь имена. data Point = Point {x::Double, y::Double} point1 = Point {x = 1.5, y = 3.0} или data Book = Book {author::String, title::String, year::Int } book1 = Book {author="Goethe", title="Faust", year=1831} Имена полей одновременно являются и функциями (как свойства в C#). > author faust "Goethe" > title faust "Faust"

  4. Множественные конструкторы Конструкторов у типа может быть много. Они могут быть константами, и тогда тип напоминает перечислитель из C#: • data Color = Red | Green | Blue • dataBool = True | False Конструкторы могут иметь параметры. data Color = Red | Green | Blue | RGB IntIntInt Последний конструктор создает значение цвета из трех целых чисел. Тип, имеющий несколько конструкторов, называют полиморфным.

  5. Параметрические типы Можно объявить и более общий тип – параметрический. Конструктор такого типа создает точки из двух любых однотипных значений. data Point a = Point a a a – тип-параметр (как в шаблонах C#). Point a a– конструктор типа. Он определяет функцию Point:: a->a->Point a которая создает точку из двух однотипных значений. data Point a = Point a a len:: Point Float -> Float len (Point x y) = sqrt (x * x + y * y)

  6. Определение типа Bool Определим самодельный логический тип в файле MyBool.hs. module MyBool where import Prelude hiding (Bool) data Bool = True | False Чтобы пользовательские типы приносили пользу, нужно определять функции для работы с ними.

  7. Функции для типа Bool module MyBool where import Prelude hiding (Bool) data Bool = True | False and:: Bool -> Bool -> Bool and True True = True and _ _ = False not:: Bool -> Bool not True = False not False = True toStr:: Bool -> String toStr True = "T" toStr False = "F" Задача. Определить функцию or.

  8. Ответ: функция or or:: Bool -> Bool -> Bool -- вариант 1 ------------------ or False False = False or _ _ = True -- вариант 2 ------------------ or x y = not (not x `and` not y)

  9. Пример определения типа – Nat Для обоснования непротиворечивости арифметики итальянский математик Джузеппе Пеано использовал числа, которые строятся рекурсивно из 0 при помощи функции Succ: 0 = 0 1= Succ 0 2= Succ (Succ 0) 3= Succ(Succ (Succ 0)) ... data Nat = Zero | Succ Nat deriving Show (+)::Nat->Nat->Nat (+) a Zero = a (+) a (Succ b) = Succ(a + b) Джузеппе Пеано Задача. Определить функцию умножения для Nat.

  10. Ответ: умножение для Nat data Nat = Zero | Succ Nat deriving Show (+)::Nat->Nat->Nat (+) a Zero = a (+) a (Succ b) = Succ(a + b) (*)::Nat->Nat->Nat (*) _ Zero = Zero (*) Zero _ = Zero (*) a (Succ Zero) = a (*) a (Succ b) = a * b + a

  11. Рекурсивные типы Рекурсивные – такие типы, в конструкторах которых присутствует сам определяемый тип. Тип Nat – рекурсивный. Если в конструкторе типа определяемый тип встречается один раз, получаются линейные структуры, если много раз – древовидные. Дадим собственное определение списка. data List a = E | L a (List a) E – означает [] (Empty) L – метка конструктора, подобного (x:xs)

  12. Пример: самодельный список import Prelude hiding ( (++), sum ) data List a = E | L a (List a) deriving Show (%):: a -> List a -> List a -- то же, что (:) (%) x xs = L x xs infixr 5 % (++)::List a -> List a -> List a (++) E xs = xs (++) (L x xs) ys = x % (xs ++ ys) sum :: Num a => List a -> a sum E = 0 sum (L x xs) = x + sum xs -- примеры списков list1 = 1 % 2 % 3 % E list2 = L 1 (L 2 (L 3 E))

  13. Тип Tree – бинарное дерево Каждый узел дерева содержит значение типа aи может ссылаться на два дочерние узла. Пустое дерево будем обозначать Nil. data Tree a = Node a (Tree a) (Tree a) | Nil deriving (Show, Eq) Принадлежность типа к классам Show и Eqозначает, что деревья можно выводить на экран и сравнивать между собой. countNodes:: (Tree a) -> Int countNodes Nil = 0 countNodes (Node _ t1 t2) = 1 + countNodes t1 + countNodes t2 Задача. Объявить функцию копирования дерева copyTree::(Tree a) -> (Tree a)

  14. Ответ copyTree::(Tree a) -> (Tree a) copyTree Nil = Nil copyTree (Node a t1 t2) = Node a (copyTree t1) (copyTree t2)

  15. Арифметическое выражение Арифметические выражения можно однозначно представить в виде дерева. Для простоты ограничимся только целыми числами и операциями сложения и умножения. Дерево выражения (2 + 3) * (4 + 5) • Листьями дерева всегда являются числовые константы, внутренними узлами – арифметические операции. 2 3 4 5 + + * data Expr = C Integer -- константа | A ExprExpr -- сложение | M ExprExpr -- умножение

  16. Арифметическое выражение import Prelude hiding ((+), (*)) import Mock data Expr = C Integer | A ExprExpr -- A - сложение | M ExprExpr -- M - умножение deriving Show e = (M (A (C 2) (C 3)) (A (C 4) (C 5))) eval :: Expr -> Integer eval (C x) = x eval (A x y) = eval x `plus` eval y eval (M x y) = eval x `star` eval y 2 3 4 5 (+) = A (*) = M infixl 4 + infixl 5 * e1 = C 2 + C 3 * C 5 + + *

  17. Класс типов Класс типов эквивалентен понятию "интерфейс" в императивном программировании. Любой интерфейс выделяет среди всех типов те, которые его реализуют. • Пример – класс Show. • Типы из этого класса могут быть показаны в интерпретаторе, т.к. для них реализована функция show • class Show a where • show :: a -> String • -- и др.функции • Класс содержит только объявления функций, их определения находятся в реализациях класса. • Реализуем класс Show для типа Boolих модуля MyBool.

  18. Примеры реализации класса -- Реализация класса Show для типа Bool. instance Show Boolwhere show True = "T" show False = "F" -- Реализация класса Show для типа Point a. instance Show a => Show (Point a) where show (Point x y) = "x=" ++ (show x) ++ " y=" ++ (show y)

  19. Классы из Prelude Show (show) Read (read) Eq ((==), (/=) ) Ord ((<), (<=), (>), (>=), max, min) Bounded (minBound, maxBound) Enum ( succ, pred, …) Num Real Integral Fractional Floating Monad Functor

  20. Вывод реализации Реализацию некоторых классов компилятор способен вывести самостоятельно. Чтобы санкционировать этот вывод, существует ключевое слово deriving. dataBool = True | False deriving (Show, Read, Eq, Ord)

  21. Самостоятельно Для типа Nat определите операции: возведения в степень вычисления факториала преобразования к целому преобразования из целого взятия предыдущего числа (для Zero это должно быть Zero). Для типа Nat реализуйте класс Eq, Ord.

More Related