Skip to content

Commit f7020ed

Browse files
committed
initial commit, without homework
0 parents  commit f7020ed

File tree

3 files changed

+372
-0
lines changed

3 files changed

+372
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*~

ITMOPrelude/List.hs

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
{-# LANGUAGE NoImplicitPrelude #-}
2+
module ITMOPrelude.List where
3+
4+
import Prelude (Show,Read,error)
5+
import ITMOPrelude.Primitive
6+
7+
---------------------------------------------
8+
-- Что надо делать?
9+
--
10+
-- Все undefined превратить в требуемые термы.
11+
-- Звёздочкой (*) отмечены места, в которых может потребоваться думать.
12+
13+
---------------------------------------------
14+
-- Определение
15+
16+
data List a = Nil | Cons a (List a) deriving (Show,Read)
17+
18+
---------------------------------------------
19+
-- Операции
20+
21+
-- Длина списка
22+
length :: List a -> Nat
23+
length = undefined
24+
25+
-- Склеить два списка за O(length a)
26+
(++) :: List a -> List a -> List a
27+
a ++ b = undefined
28+
29+
-- Список без первого элемента
30+
tail :: List a -> List a
31+
tail = undefined
32+
33+
-- Список без последнего элемента
34+
init :: List a -> List a
35+
init = undefined
36+
37+
-- Первый элемент
38+
head :: List a -> a
39+
head = undefined
40+
41+
-- Последний элемент
42+
last :: List a -> a
43+
last = undefined
44+
45+
-- n первых элементов списка
46+
take :: Nat -> List a -> List a
47+
take = undefined
48+
49+
-- Список без n первых элементов
50+
drop :: Nat -> List a -> List a
51+
drop = undefined
52+
53+
-- Оставить в списке только элементы удовлетворяющие p
54+
filter :: (a -> Bool) -> List a -> List a
55+
filter p = undefined
56+
57+
-- Обобщённая версия. Вместо "выбросить/оставить" p
58+
-- говорит "выбросить/оставить b".
59+
gfilter :: (a -> Maybe b) -> List a -> List b
60+
gfilter p = undefined
61+
62+
-- Копировать из списка в результат до первого нарушения предиката
63+
-- takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2]
64+
takeWhile :: (a -> Bool) -> List a -> List a
65+
takeWhile = undefined
66+
67+
-- Не копировать из списка в результат до первого нарушения предиката,
68+
-- после чего скопировать все элементы, включая первый нарушивший
69+
-- dropWhile (< 3) [1,2,3,4,1,2,3,4] == [3,4,1,2,3,4]
70+
dropWhile :: (a -> Bool) -> List a -> List a
71+
dropWhile = undefined
72+
73+
-- Разбить список в пару (найбольший префикс удовлетворяющий p, всё остальное)
74+
span :: (a -> Bool) -> List a -> Pair (List a) (List a)
75+
span p = undefined
76+
77+
-- Разбить список по предикату на (takeWhile p xs, dropWhile p xs),
78+
-- но эффективнее
79+
break :: (a -> Bool) -> List a -> Pair (List a) (List a)
80+
break = undefined
81+
82+
-- n-ый элемент списка (считая с нуля)
83+
(!!) :: List a -> Nat -> a
84+
Nil !! n = error "!!: empty list"
85+
l !! n = undefined
86+
87+
-- Список задом на перёд
88+
reverse :: List a -> List a
89+
reverse = undefined
90+
91+
-- (*) Все подсписки данного списка
92+
subsequences :: List a -> List (List a)
93+
subsequences Nil = Cons Nil Nil
94+
subsequences (Cons x xs) = undefined
95+
96+
-- (*) Все перестановки элементов данного списка
97+
permutations :: List a -> List (List a)
98+
permutations = undefined
99+
100+
-- (*) Если можете. Все перестановки элементов данного списка
101+
-- другим способом
102+
permutations' :: List a -> List (List a)
103+
permutations' = undefined
104+
105+
-- Повторяет элемент бесконечное число раз
106+
repeat :: a -> List a
107+
repeat = undefined
108+
109+
-- Левая свёртка
110+
-- порождает такое дерево вычислений:
111+
-- f
112+
-- / \
113+
-- f ...
114+
-- / \
115+
-- f l!!2
116+
-- / \
117+
-- f l!!1
118+
-- / \
119+
-- z l!!0
120+
foldl :: (a -> b -> a) -> a -> List b -> a
121+
foldl f z l = undefined
122+
123+
-- Тот же foldl, но в списке оказываются все промежуточные результаты
124+
-- last (scanl f z xs) == foldl f z xs
125+
scanl :: (a -> b -> a) -> a -> List b -> List a
126+
scanl = undefined
127+
128+
-- Правая свёртка
129+
-- порождает такое дерево вычислений:
130+
-- f
131+
-- / \
132+
-- l!!0 f
133+
-- / \
134+
-- l!!1 f
135+
-- / \
136+
-- l!!2 ...
137+
-- \
138+
-- z
139+
--
140+
foldr :: (a -> b -> b) -> b -> List a -> b
141+
foldr f z l = undefined
142+
143+
-- Аналогично
144+
-- head (scanr f z xs) == foldr f z xs.
145+
scanr :: (a -> b -> b) -> b -> [a] -> [b]
146+
scanr = undefined
147+
148+
-- Должно завершаться за конечное время
149+
finiteTimeTest = take (Succ $ Succ $ Succ $ Succ Zero) $ foldr (Cons) Nil $ repeat Zero
150+
151+
-- Применяет f к каждому элементу списка
152+
map :: (a -> b) -> List a -> List b
153+
map f l = undefined
154+
155+
-- Склеивает список списков в список
156+
concat :: List (List a) -> List a
157+
concat = undefined
158+
159+
-- Эквивалент (concat . map), но эффективнее
160+
concatMap :: (a -> List b) -> List a -> List b
161+
concatMap = undefined
162+
163+
-- Сплющить два списка в список пар длинны min (length a, length b)
164+
zip :: List a -> List b -> List (Pair a b)
165+
zip a b = undefined
166+
167+
-- Аналогично, но плющить при помощи функции, а не конструктором Pair
168+
zipWith :: (a -> b -> c) -> List a -> List b -> List c
169+
zipWith = undefined

ITMOPrelude/Primitive.hs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
{-# LANGUAGE NoImplicitPrelude #-}
2+
module ITMOPrelude.Primitive where
3+
4+
import Prelude (Show,Read)
5+
6+
---------------------------------------------
7+
-- Синтаксис лямбда-выражений
8+
9+
-- Эквивалентные определения
10+
example1 x = x
11+
example1' = \x -> x
12+
example1'' = let y = \x -> x in y
13+
example1''' = y where
14+
y = \x -> x
15+
16+
-- Снова эквивалентные определения
17+
example2 x y = x %+ y
18+
example2' x = \y -> x %+ y
19+
example2'' = \x -> \y -> x %+ y
20+
example2''' = \x y -> x %+ y
21+
example2'''' = let z = \x y -> x %+ y in z
22+
example2''''' = z where
23+
z x = \y -> x %+ y
24+
25+
-- Зацикленное выражение
26+
undefined = undefined
27+
28+
-- Ниже следует реализовать все термы, состоящие из undefined заглушки.
29+
-- Любые термы можно переписывать (natEq и natLe --- хорошие кандидаты).
30+
31+
-------------------------------------------
32+
-- Примитивные типы
33+
34+
-- Тип с единственным элементом
35+
data Unit = Unit deriving (Show,Read)
36+
37+
-- Пара, произведение
38+
data Pair a b = Pair { fst :: a, snd :: b } deriving (Show,Read)
39+
40+
-- Вариант, копроизведение
41+
data Either a b = Left a | Right b deriving (Show,Read)
42+
43+
-- Частый частный случай, изоморфно Either Unit a
44+
data Maybe a = Nothing | Just a deriving (Show,Read)
45+
46+
-- Частый частный случай, изоморфно Either Unit Unit
47+
data Bool = False | True deriving (Show,Read)
48+
49+
-- Следует отметить, что встроенный if с этим Bool использовать нельзя,
50+
-- зато case всегда работает.
51+
52+
-- Ну или можно реализовать свой if
53+
if' True a b = a
54+
if' False a b = b
55+
56+
-- Трихотомия. Замечательный тип, показывающий результат сравнения
57+
data Tri = LE | EQ | GT deriving (Show,Read)
58+
59+
-------------------------------------------
60+
-- Натуральные числа
61+
62+
data Nat = Zero | Succ Nat deriving (Show,Read)
63+
64+
natZero = Zero -- 0
65+
natOne = Succ Zero -- 1
66+
67+
-- Сравнивает два натуральных числа
68+
natCmp :: Nat -> Nat -> Tri
69+
natCmp = undefined
70+
71+
-- n совпадает с m
72+
natEq :: Nat -> Nat -> Bool
73+
natEq Zero Zero = True
74+
natEq Zero (Succ _) = False
75+
natEq (Succ _) Zero = False
76+
natEq (Succ n) (Succ m) = natEq n m
77+
78+
-- n меньше m
79+
natLe :: Nat -> Nat -> Bool
80+
natLe Zero Zero = False
81+
natLe Zero (Succ m) = True
82+
natLe (Succ n) Zero = False
83+
natLe (Succ n) (Succ m) = natLe n m
84+
85+
infixl 6 +.
86+
-- Сложение для натуральных чисел
87+
(+.) :: Nat -> Nat -> Nat
88+
Zero +. m = m
89+
(Succ n) +. m = Succ (n +. m)
90+
91+
infixl 6 -.
92+
-- Вычитание для натуральных чисел
93+
(-.) :: Nat -> Nat -> Nat
94+
n -. m = undefined
95+
96+
infixl 7 *.
97+
-- Умножение для натуральных чисел
98+
(*.) :: Nat -> Nat -> Nat
99+
Zero *. m = Zero
100+
(Succ n) *. m = m +. (n *. m)
101+
102+
-- Целое и остаток от деления n на m
103+
natDivMod :: Nat -> Nat -> Pair Nat Nat
104+
natDivMod n m = undefined
105+
106+
natDiv n = fst . natDivMod n -- Целое
107+
natMod n = snd . natDivMod n -- Остаток
108+
109+
-- Поиск GCD алгоритмом Евклида (должен занимать 2 (вычислителельная часть) + 1 (тип) строчки)
110+
gcd :: Nat -> Nat -> Nat
111+
gcd = undefined
112+
113+
-------------------------------------------
114+
-- Целые числа
115+
116+
-- Требуется, чтобы представление каждого числа было единственным
117+
data Int = UNDEFINED deriving (Show,Read)
118+
119+
intZero = undefined -- 0
120+
intOne = undefined -- 1
121+
intNegOne = undefined -- -1
122+
123+
-- n -> - n
124+
intNeg :: Int -> Int
125+
intNeg = undefined
126+
127+
-- Дальше также как для натуральных
128+
intCmp :: Int -> Int -> Tri
129+
intCmp = undefined
130+
131+
intEq :: Int -> Int -> Bool
132+
intEq = undefined
133+
134+
intLe :: Int -> Int -> Bool
135+
intLe = undefined
136+
137+
infixl 6 .+., .-.
138+
-- У меня это единственный страшный терм во всём файле
139+
(.+.) :: Int -> Int -> Int
140+
n .+. m = undefined
141+
142+
(.-.) :: Int -> Int -> Int
143+
n .-. m = n .+. (intNeg m)
144+
145+
infixl 7 .*.
146+
(.*.) :: Int -> Int -> Int
147+
n .*. m = undefined
148+
149+
-------------------------------------------
150+
-- Рациональные числа
151+
152+
data Rat = Rat Int Nat
153+
154+
ratNeg :: Rat -> Rat
155+
ratNeg (Rat x y) = Rat (intNeg x) y
156+
157+
-- У рациональных ещё есть обратные элементы
158+
ratInv :: Rat -> Rat
159+
ratInv = undefined
160+
161+
-- Дальше как обычно
162+
ratCmp :: Rat -> Rat -> Tri
163+
ratCmp = undefined
164+
165+
ratEq :: Rat -> Rat -> Bool
166+
ratEq = undefined
167+
168+
ratLe :: Rat -> Rat -> Bool
169+
ratLe = undefined
170+
171+
infixl 7 %+, %-
172+
(%+) :: Rat -> Rat -> Rat
173+
n %+ m = undefined
174+
175+
(%-) :: Rat -> Rat -> Rat
176+
n %- m = n %+ (ratNeg m)
177+
178+
infixl 7 %*, %/
179+
(%*) :: Rat -> Rat -> Rat
180+
n %* m = undefined
181+
182+
(%/) :: Rat -> Rat -> Rat
183+
n %/ m = n %* (ratInv m)
184+
185+
-------------------------------------------
186+
-- Операции над функциями.
187+
-- Определены здесь, но использовать можно и выше
188+
189+
infixr 9 .
190+
f . g = \ x -> f (g x)
191+
192+
infixr 0 $
193+
f $ x = f x
194+
195+
-- Эквивалентные определения
196+
example3 a b c = gcd a (gcd b c)
197+
example3' a b c = gcd a $ gcd b c
198+
example3'' a b c = ($) (gcd a) (gcd b c)
199+
200+
-- И ещё эквивалентные определения
201+
example4 a b x = (gcd a (gcd b x))
202+
example4' a b = gcd a . gcd b

0 commit comments

Comments
 (0)