#ukrhaskell — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #ukrhaskell, aggregated by home.social.
-
CW: Кортежі у :haskell:
Кортежі — це гетерогенні структури даних, фіксованої довжини, та з елементами здебільшого різних типів.
Створюються вони за допомоги бінарного оператора
(,).> (,) 'c' True ('c',True)При цьому в нас виходить двох елементний кортеж, часто його ще називають парою. Але кортежі можуть бути й довші, або коротші.
Найкоротший кортеж - це порожній кортеж.
> () ()Якщо нам потрібно більше елементів, то значить треба додати більше ком. Але кортежу довжиною в один елемент не існує, оскільки синтаксично його не можливо створити через те що елемент в дужках, наприклад
(3), це просто групування.> (,,) 4 'a' False (4,'a',False) > (,,,) 4 'a' False "Haskell" (4,'a',False,"Haskell")Але створювати таким синтаксисом не дуже зручно, оскільки нам постійно потрібно рахувати кількість аргументів, й вказувати відповідну кількість ком, на одну менше за значень. Для спрощення, синтаксис хаскеля трохи підцукрили, й дозволили робити нам так як вони відображаються.
> (4, 'a', False, "Haskell") (4,'a',False,"Haskell")Тепер перейдемо до їхніх типів.
Нагадую: простори імен типів та всього іншого відокремлені.
Тип кортежів це
().> :t () () :: ()Якщо це не порожній кортеж, то й тип не порожній.
> :t ('c', True) ('c', True) :: (Char, Bool)Це все добре, але треба якось же із ними працювати й отримувати окремі елементи. У стандартній бібліотеці для цього є кілька готових функцій, наприклад візьмемо
fstкотра повертає перший елемент, таsndкотра повертає другий елемент.> p = (1,2) > fst p 1 > snd p 2Ці функції працюють тільки з парами, і реалізовуються через зіставлення.
fst (x,_) = x snd (_,y) = y -
CW: Налаштування GHCI, інтерпритатора :haskell:
Під час вивчання
Haskell, та й, мабуть, під час роботи з ним, часто використовується інтерпретатор. На жаль, за замовчуванням він не дуже зручний, але частково ми можемо виправити це простими налаштуваннями.Всі налаштування робляться через його команду
:set. До прикладу, часто може знадобитися переглядати типи функцій, чи їхніх значень після виконання. Робиться це командою:typeпередаючи певну конструкцію, але можна увімкнути автоматичний друк типів при виконанні кожної інструкції командою:set +t. Після цього виконання буде виглядати так:ghci> 4 4 it :: Num a => a ghci> 'N' 'N' it :: Char ghci> 2 + 2 * 4 10 it :: Num a => aТепер нам не потрібно виконувати окремі команди, щоб побачити значення та тип результату.
Також можна змінити підказку (prompt) щоб не дивитись кожнісінький раз на те що ми й так знаємо, а саме що ми у
ghci.ghci> :set prompt "> " > "It's a String" "It's a String" it :: String >Це вже краще, але далеко до ідеалу, тому додамо ще якусь корисну інформацію, окрім прибирання зайвої, наприклад номер рядка й завантажений модуль.
> :set prompt "[%l] %s> " [7] Prelude>Так вже цікавіше.
Є ще одна штучка котра може нам іноді знадобитись при тестах.
[1] Prelude> f = do <interactive>:1:5: error: [GHC-82311] Empty 'do' block Suggested fix: Perhaps you intended to use NondecreasingIndentation [2] Prelude> :set +m [3] Prelude> f = do ghci| putStrLn "Привіт всім хаскелятам та хаскелищам!" ghci| [6] Prelude> f Привіт всім хаскелятам та хаскелищам! [7] Prelude>:set +mдозволяє писати багато рядкові конструкції.Це все добре, але після перезапуску, всі налаштування загубляться у просторі всесвіту й ви втратите свої персональні налаштунки, а допомагає уникнути цього
.ghciфайл у домашній теці, або у поточній. Просто запишіть у нього всі необхідні команди й ви спаслись. -
CW: Налаштування GHCI, інтерпритатора :haskell:
Під час вивчання
Haskell, та й, мабуть, під час роботи з ним, часто використовується інтерпретатор. На жаль, за замовчуванням він не дуже зручний, але частково ми можемо виправити це простими налаштуваннями.Всі налаштування робляться через його команду
:set. До прикладу, часто може знадобитися переглядати типи функцій, чи їхніх значень після виконання. Робиться це командою:typeпередаючи певну конструкцію, але можна увімкнути автоматичний друк типів при виконанні кожної інструкції командою:set +t. Після цього виконання буде виглядати так:ghci> 4 4 it :: Num a => a ghci> 'N' 'N' it :: Char ghci> 2 + 2 * 4 10 it :: Num a => aТепер нам не потрібно виконувати окремі команди, щоб побачити значення та тип результату.
Також можна змінити підказку (prompt) щоб не дивитись кожнісінький раз на те що ми й так знаємо, а саме що ми у
ghci.ghci> :set prompt "> " > "It's a String" "It's a String" it :: String >Це вже краще, але далеко до ідеалу, тому додамо ще якусь корисну інформацію, окрім прибирання зайвої, наприклад номер рядка й завантажений модуль.
> :set prompt "[%l] %s> " [7] Prelude>Так вже цікавіше.
Є ще одна штучка котра може нам іноді знадобитись при тестах.
[1] Prelude> f = do <interactive>:1:5: error: [GHC-82311] Empty 'do' block Suggested fix: Perhaps you intended to use NondecreasingIndentation [2] Prelude> :set +m [3] Prelude> f = do ghci| putStrLn "Привіт всім хаскелятам та хаскелищам!" ghci| [6] Prelude> f Привіт всім хаскелятам та хаскелищам! [7] Prelude>:set +mдозволяє писати багато рядкові конструкції.Це все добре, але після перезапуску, всі налаштування загубляться у просторі всесвіту й ви втратите свої персональні налаштунки, а допомагає уникнути цього
.ghciфайл у домашній теці, або у поточній. Просто запишіть у нього всі необхідні команди й ви спаслись. -
CW: Налаштування GHCI, інтерпритатора :haskell:
Під час вивчання
Haskell, та й, мабуть, під час роботи з ним, часто використовується інтерпретатор. На жаль, за замовчуванням він не дуже зручний, але частково ми можемо виправити це простими налаштуваннями.Всі налаштування робляться через його команду
:set. До прикладу, часто може знадобитися переглядати типи функцій, чи їхніх значень після виконання. Робиться це командою:typeпередаючи певну конструкцію, але можна увімкнути автоматичний друк типів при виконанні кожної інструкції командою:set +t. Після цього виконання буде виглядати так:ghci> 4 4 it :: Num a => a ghci> 'N' 'N' it :: Char ghci> 2 + 2 * 4 10 it :: Num a => aТепер нам не потрібно виконувати окремі команди, щоб побачити значення та тип результату.
Також можна змінити підказку (prompt) щоб не дивитись кожнісінький раз на те що ми й так знаємо, а саме що ми у
ghci.ghci> :set prompt "> " > "It's a String" "It's a String" it :: String >Це вже краще, але далеко до ідеалу, тому додамо ще якусь корисну інформацію, окрім прибирання зайвої, наприклад номер рядка й завантажений модуль.
> :set prompt "[%l] %s> " [7] Prelude>Так вже цікавіше.
Є ще одна штучка котра може нам іноді знадобитись при тестах.
[1] Prelude> f = do <interactive>:1:5: error: [GHC-82311] Empty 'do' block Suggested fix: Perhaps you intended to use NondecreasingIndentation [2] Prelude> :set +m [3] Prelude> f = do ghci| putStrLn "Привіт всім хаскелятам та хаскелищам!" ghci| [6] Prelude> f Привіт всім хаскелятам та хаскелищам! [7] Prelude>:set +mдозволяє писати багато рядкові конструкції.Це все добре, але після перезапуску, всі налаштування загубляться у просторі всесвіту й ви втратите свої персональні налаштунки, а допомагає уникнути цього
.ghciфайл у домашній теці, або у поточній. Просто запишіть у нього всі необхідні команди й ви спаслись. -
CW: :haskell: функції error та undefined
errorтаundefinedце не звичайні функції. Крім того, що вони поліморфні, та ще й переривають виконання.Перша приймає рядок з повідомленням помилки й виводить його на екран, а друга просто перериває обчислення.
Їхній поліморфізм полягає в типі повернення, й потрібен для того, щоб можна було їх викликати будь-де.
λ> error "Упс, щось не так." *** Exception: Упс, щось не так. CallStack (from HasCallStack): error, called at <interactive>:4:1 in interactive:Ghci1 λ> undefined *** Exception: Prelude.undefined CallStack (from HasCallStack): undefined, called at <interactive>:5:1 in interactive:Ghci1#ukrhaskell #haskell #error #undefined #поліморфізм #програмування
-
CW: :haskell:, конструкція where
Окрім виразу
let inє ще схожа конструкціяwhere. Вона виконує ту ж функцію, але трохи по інакшому.g n = x+2*x where x = n^3+2На перший погляд, змінилась тільки послідовність оголошення та використання функцій, і це майже правильно. Ключова відмінність у, тому що
let inце вираз, аwhereконструкція. Тому друге можна використовувати там де не можна перше, наприклад при використанні кількох визначень з охоронними виразами чи зіставленнями.f x | x > 0 = y * 2 | x < 0 = y / 2 where y = cos x^2На жаль приклад дуже не дуже, але є що є.
Тут оголошені функції після
whareможна використовувати в усіх визначенняхf, й навіть в охоронних виразах.let inтакого не дозволяє.#ukrhaskell #haskell #where #letin #вираз #конструкція #підфункції #охоронні_вирази #програмування
-
CW: Відступи в синтаксисі :haskell:
У синтаксисі
Haskellяк і уPythonвідступи грають важливу роль. Коли у нас є довге визначення і ми хочемо розбити його на менші й зрозуміліші частини потрібно якось уточнити що це не нове оголошення, а продовження попереднього.Для прикладу візьмемо вираз
if then else, бо інші ми ще не вивчали.f x = if x > 0 then True else FalseУ цьому виразі немає великих значень чи формул, але ми розглянемо його для простого розуміння. Розбити його на окремі рядки ми можемо так.
f x = if x > 0 then True else FalseАбо так.
f x = if x > 0 then True else FalseКількість пробілів не має значення. Головне що їх було, або таж кількість, або більше. Якщо відступ відсутній, то це означає що починається нове оголошення.
!! Один символ табуляції завжди вважається як 8 пробілів.
#ukrhaskell #програмування #haskell #відсупи #табуляція #синтаксис #syntax #spaces #tab
-
CW: Швидкий запуск програми на :haskell:
Під час розробки часто потрібно перезапускати програму перевіряючи її поведінку. Але робити це за допомоги інтерпретатора
ghciзапускаючи функцію не завжди зручно, та й збирати компіляторомghcі запускати бінарник також. Тому для зручності було зробленоrunghc. Це команда яка компілює код і зразу його виконує не зберігаючи у файл.$ runghc main.hs#ukrhaskell #haskell #ghc #ghci #runghc #запуск #програмування
-
CW: Швидкий запуск програми на :haskell:
Під час розробки часто потрібно перезапускати програму перевіряючи її поведінку. Але робити це за допомоги інтерпретатора
ghciзапускаючи функцію не завжди зручно, та й збирати компіляторомghcі запускати бінарник також. Тому для зручності було зробленоrunghc. Це команда яка компілює код і зразу його виконує не зберігаючи у файл.$ runghc main.hs#ukrhaskell #haskell #ghc #ghci #runghc #запуск #програмування
-
CW: Оператор $ у :haskell:
Через те що у
Haskellаргументи функції не вкладаються у дужки при спробі передати результат однієї функції в іншу потрібно використати дужки для групування.foo bar x -- Функції передаються два аргументи bar і x foo (bar x) -- Функції bar передається аргумент x і її результат підставиться як один аргумент функції fooУ цьому простому прикладі все виглядає просто і зрозуміло, але якщо у нас був би складніший вираз з іншими дужками все виглядало б не так зрозуміло.
Для полегшення додали спеціальний оператор зниження пріоритету. Складається він з одного символу
$. Використати його ми можемо тут підставивши між функціями.foo $ bar xРезультат буде той же що й з дужками.
Цей оператор має праву асоціативність і найнижчий пріоритет. Перевірити це ми можемо в інтерпретаторі.
> :i ($) ($) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $Тако ж у цьому повідомленні ми бачимо тип цього оператора. Він приймає іншу функцію й аргумент цієї функції, а повертає результат цієї функції. Визначення цього оператора таке.
($) f x = f x#ukrhaskell #програмування #haskell #оператор #$ #пріоритет #функції