home.social

#ukrhaskell — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #ukrhaskell, aggregated by home.social.

  1. 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
    

    #ukrhaskell #haskell #tuple #кортежі #типи #програмування

  2. 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 файл у домашній теці, або у поточній. Просто запишіть у нього всі необхідні команди й ви спаслись.

    #ukrhaskell #haskell #ghci #налаштування #prompt #set

  3. 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 файл у домашній теці, або у поточній. Просто запишіть у нього всі необхідні команди й ви спаслись.

    #ukrhaskell #haskell #ghci #налаштування #prompt #set

  4. 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 файл у домашній теці, або у поточній. Просто запишіть у нього всі необхідні команди й ви спаслись.

    #ukrhaskell #haskell #ghci #налаштування #prompt #set

  5. 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 #поліморфізм #програмування

  6. 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 #вираз #конструкція #підфункції #охоронні_вирази #програмування

  7. 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 #вираз #конструкція #підфункції #охоронні_вирази #програмування

  8. 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 #вираз #конструкція #підфункції #охоронні_вирази #програмування

  9. 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 #вираз #конструкція #підфункції #охоронні_вирази #програмування

  10. 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 #вираз #конструкція #підфункції #охоронні_вирази #програмування

  11. 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

  12. 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

  13. 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

  14. 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

  15. 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

  16. CW: Швидкий запуск програми на :haskell:

    Під час розробки часто потрібно перезапускати програму перевіряючи її поведінку. Але робити це за допомоги інтерпретатора ghci запускаючи функцію не завжди зручно, та й збирати компілятором ghc і запускати бінарник також. Тому для зручності було зроблено runghc. Це команда яка компілює код і зразу його виконує не зберігаючи у файл.

    $ runghc main.hs
    

    #ukrhaskell #haskell #ghc #ghci #runghc #запуск #програмування

  17. CW: Швидкий запуск програми на :haskell:

    Під час розробки часто потрібно перезапускати програму перевіряючи її поведінку. Але робити це за допомоги інтерпретатора ghci запускаючи функцію не завжди зручно, та й збирати компілятором ghc і запускати бінарник також. Тому для зручності було зроблено runghc. Це команда яка компілює код і зразу його виконує не зберігаючи у файл.

    $ runghc main.hs
    

    #ukrhaskell #haskell #ghc #ghci #runghc #запуск #програмування

  18. @balaraz розкажіть, як ви зараз думаєте, навіщо оцей хаскель потрібен, які у нього переваги над імперативними мовами? (btw тег #ukrhaskell прикольний, буду користуватись)

  19. 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 #оператор #$ #пріоритет #функції

  20. 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 #оператор #$ #пріоритет #функції

  21. 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 #оператор #$ #пріоритет #функції

  22. 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 #оператор #$ #пріоритет #функції

  23. 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 #оператор #$ #пріоритет #функції

  24. CW: Охоронні вирази в :haskell:

    За допомоги зіставлення ми можемо розділити виконання на кілька гілок залежно від умови, але ця умова може тільки перевіряти на рівність. Коли нам потрібно використати складнішу умову на допомогу приходять охоронні вирази.

    Оголошуються ці вирази після аргументів відділяючись вертикальною лінією.

    f x | x > 0 = x
    

    Цю функцію можна викликати тільки на додатних числах.

    Також ми можемо обʼєднати зіставлення й охоронні вирази.

    f 0 = 0
    f x | x > 0 = 2 / x
    

    Якщо нам потрібно виконувати різні дії залежно від різних умов ми можемо оголошувати кілька різних функцій.

    f x | x > 0 = x * 2
    f x | x < 0 = x * (-2)
    

    Якщо спробуємо викликати цю функцію на значенні 0, то отримаємо помилку.

    *** Exception: Demo.hs:(18,1)-(19,22): Non-exhaustive patterns in function f
    

    У попередньому дописі я писав що можна оголошувати тільки одну функцію з константою, а не зіставленням, але як ви вже могли замітити, то з охоронними виразами це обмеження зникає.

    У такому оголошенні є мінус, а саме те що ми повторюємо назву функції та її аргументи, тому ми можемо спростити це оголошення ось так.

    f 0 = 0
    f x | x > 0 = x * 2
        | x < 0 = x * (-2)
    

    Це абсолютно рівні оголошення, тільки тут ми ще додали зіставлення для нуля.

    #ukrhaskell #програмування #haskell #охоронні_вирази #зіставлення #умови #функції

  25. CW: Охоронні вирази в :haskell:

    За допомоги зіставлення ми можемо розділити виконання на кілька гілок залежно від умови, але ця умова може тільки перевіряти на рівність. Коли нам потрібно використати складнішу умову на допомогу приходять охоронні вирази.

    Оголошуються ці вирази після аргументів відділяючись вертикальною лінією.

    f x | x > 0 = x
    

    Цю функцію можна викликати тільки на додатних числах.

    Також ми можемо обʼєднати зіставлення й охоронні вирази.

    f 0 = 0
    f x | x > 0 = 2 / x
    

    Якщо нам потрібно виконувати різні дії залежно від різних умов ми можемо оголошувати кілька різних функцій.

    f x | x > 0 = x * 2
    f x | x < 0 = x * (-2)
    

    Якщо спробуємо викликати цю функцію на значенні 0, то отримаємо помилку.

    *** Exception: Demo.hs:(18,1)-(19,22): Non-exhaustive patterns in function f
    

    У попередньому дописі я писав що можна оголошувати тільки одну функцію з константою, а не зіставленням, але як ви вже могли замітити, то з охоронними виразами це обмеження зникає.

    У такому оголошенні є мінус, а саме те що ми повторюємо назву функції та її аргументи, тому ми можемо спростити це оголошення ось так.

    f 0 = 0
    f x | x > 0 = x * 2
        | x < 0 = x * (-2)
    

    Це абсолютно рівні оголошення, тільки тут ми ще додали зіставлення для нуля.

    #ukrhaskell #програмування #haskell #охоронні_вирази #зіставлення #умови #функції