Лекция
This presentation is the property of its rightful owner.
Sponsored Links
1 / 21

типы и классы PowerPoint PPT Presentation


  • 111 Views
  • Uploaded on
  • Presentation posted in: General

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

Download Presentation

типы и классы

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


2429943

Лекция

типы и классы


2429943

Пользовательские типы

Для задания пользовательских типов служит ключевое слово data.

Объявим тип Point- точка на плоскости.

Если понимать точку как два вещественных числа, то определение типа будет таким.

data Point = Point Double Double

data– ключевое слово.

Point – имя типа, пишется с большой буквы.

Point Double Double– конструктор, создает точку из двух чисел.

Первое слово конструктора – метка.


2429943

Именованные поля

Тип можно объявить так, что отдельные части его значения будут иметь имена.

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"


2429943

Множественные конструкторы

Конструкторов у типа может быть много. Они могут быть константами, и тогда тип напоминает перечислитель из C#:

  • data Color = Red | Green | Blue

  • dataBool = True | False

Конструкторы могут иметь параметры.

data Color = Red | Green | Blue | RGB IntIntInt

Последний конструктор создает значение цвета из трех целых чисел.

Тип, имеющий несколько конструкторов, называют полиморфным.


2429943

Параметрические типы

Можно объявить и более общий тип – параметрический. Конструктор такого типа создает точки из двух любых однотипных значений.

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)


2429943

Определение типа Bool

Определим самодельный логический тип в файле MyBool.hs.

module MyBool where

import Prelude hiding (Bool)

data Bool = True | False

Чтобы пользовательские типы приносили пользу, нужно определять функции для работы с ними.


2429943

Функции для типа 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.


2429943

Ответ: функция or

or:: Bool -> Bool -> Bool

-- вариант 1 ------------------

or False False = False

or _ _ = True

-- вариант 2 ------------------

or x y = not (not x `and` not y)


2429943

Пример определения типа – 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.


2429943

Ответ: умножение для 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


2429943

Рекурсивные типы

Рекурсивные – такие типы, в конструкторах которых присутствует сам определяемый тип. Тип Nat – рекурсивный.

Если в конструкторе типа определяемый тип встречается один раз, получаются линейные структуры, если много раз – древовидные.

Дадим собственное определение списка.

data List a = E | L a (List a)

E – означает [] (Empty)

L – метка конструктора, подобного (x:xs)


2429943

Пример: самодельный список

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))


2429943

Тип 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)


2429943

Ответ

copyTree::(Tree a) -> (Tree a)

copyTree Nil = Nil

copyTree (Node a t1 t2) = Node a (copyTree t1) (copyTree t2)


2429943

Арифметическое выражение

Арифметические выражения можно однозначно представить в виде дерева. Для простоты ограничимся только целыми числами и операциями сложения и умножения.

Дерево выражения (2 + 3) * (4 + 5)

  • Листьями дерева всегда являются числовые константы, внутренними узлами – арифметические операции.

2

3

4

5

+

+

*

data Expr = C Integer -- константа

| A ExprExpr -- сложение

| M ExprExpr -- умножение


2429943

Арифметическое выражение

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

+

+

*


2429943

Класс типов

Класс типов эквивалентен понятию "интерфейс" в императивном программировании.

Любой интерфейс выделяет среди всех типов те, которые его реализуют.

  • Пример – класс Show.

  • Типы из этого класса могут быть показаны в интерпретаторе, т.к. для них реализована функция show

    • class Show a where

    • show :: a -> String

    • -- и др.функции

  • Класс содержит только объявления функций, их определения находятся в реализациях класса.

  • Реализуем класс Show для типа Boolих модуля MyBool.


2429943

Примеры реализации класса

-- Реализация класса 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)


Prelude

Классы из Prelude

Show(show)

Read (read)

Eq ((==), (/=) )

Ord ((<), (<=), (>), (>=), max, min)

Bounded(minBound, maxBound)

Enum( succ, pred, …)

Num

Real

Integral

Fractional

Floating

Monad

Functor


2429943

Вывод реализации

Реализацию некоторых классов компилятор способен вывести самостоятельно.

Чтобы санкционировать этот вывод, существует ключевое слово deriving.

dataBool = True | False deriving (Show, Read, Eq, Ord)


2429943

Самостоятельно

Для типа Nat определите операции:

возведения в степень

вычисления факториала

преобразования к целому

преобразования из целого

взятия предыдущего числа (для Zero это должно быть Zero).

Для типа Nat реализуйте класс Eq, Ord.


  • Login