Ці записи типів представляють собою метамова під назвою сигнатури типів (Type Signatures), який може багато чого розповісти про чисту функції і має набагато більше значення в функціональному програмуванні, ніж ви могли б очікувати.
Давайте подивимося, що таке сигнатури типів і чому ми повинні використовувати їх в нашому коді.
Сигнатура типів визначає входять і які повертаються типи для функції, іноді включаючи число аргументів, типи аргументів і порядок аргументів, що містяться в функції.
Сигнатури типів - дуже точні висловлювання, написані зверху чистих функцій, і які використовуються для відстеження їх роботи.
Сигнатури типів засновані на системі типів Хиндли-Мілнера як стандартної системі типів для мов ML. включаючи Haskell.
І якщо ви виявите будь-яку чисту функцію, задокументовану сигнатурами типів, здатність розуміти їх дасть вам наочне уявлення про роботу цієї функції.
прості функції
Вищевказана функція приймає рядок і повертає число. Якщо ми подивимося уважно, ми побачимо:
- Спочатку записується ім'я функції, а потім.
- Вхідний тип записується перед стрілкою.
- Повертається тип записується після стрілки або в самому кінці.
Пам'ятайте, що записуються тільки вхідні і повертаються типи, так що висловлювання можна прочитати ось так: «Функція length від рядка до числа».
Вищезгадана функція length також може бути записана як:
І це нормально, щоб функція мала множинні сигнатури, поки це зручно. Якщо функція стає занадто гнучкою через типів свого параметра, тоді ми повинні використовувати довільні змінні Хиндли-Мілнера - ми обговоримо їх нижче.
кілька параметрів
Функції вищого порядку
Це не функціональне програмування, якщо у нас немає функцій, які працюють на функціях
Коли функція передається в якості параметра, ми робимо висновок її в круглі дужки, щоб представити більш зрозумілу сигнатуру типів.
Вищезгадана функція є функцією «map», і вона не працює тільки з конкретними типами даних: вона може працювати з будь-яким типом масиву. Тому для опису таких функцій нам потрібно щось ще.
Довільні змінні Хиндли-Мілнера
Такі функції, какidentity, map, filterіreduce, приймають аргументи, які є занадто гнучкими, щоб визначатися конкретним типом, тому ми використовуємо класичні змінні Хиндли-Мілнераaіb
Оскільки identity завжди буде давати нам той же повертається тип для одного і того ж входить типу, ми використовували a → a для представлення його сигнатури.
Також нашу функцію length можна записати так:
Thunks або каррірованние функції
Сигнатури типів найчистіших з чистих функцій✨
Для функцій, які приймають декілька аргументів, завжди хороший варіант - карріровать їх, щоб пізніше зробити з них композицію в нашому коді. Крім того, не рекомендується використовувати довільні змінні Хиндли-Мілнера з функціями з декількома аргументами.
Часткове застосування функцій - devSchacht - Medium
"Часткове застосування функцій" is published by Roman Ponomarev in devSchacht medium.com
Стандартна функція map матиме зазначену вище сигнатуру типів. Але також можна зустріти map з такою сигнатурою типу:
Іноді ми знаємо тип масиву, що повертається map. як в цьому випадку.
Давайте подивимося на стандартні filter і reduce
Ясно, що сигнатура типів функції reduce трохи складна. Зате якщо ми зможемо зрозуміти, як написати сигнатуру типів функції reduce. ми зможемо написати сигнатуру типів для майже будь-якої функції.
Отже, перший аргумент reduce - це функція зменшення. приймаюча b і a. щоб повернути b. Це означає, що функція буде зменшувати все в тип b. тому кінцеве значення, отримане з reduce () і надане початкове значення (init), будуть мати значення типу b. І так як кожне окреме значення зі списку типу a буде проходити через цю функцію зменшення, тому другий аргумент функції зменшення повинен бути типу a. Тому така сигнатура типів reduce () є виправданою.
довільні теореми
Інше призначення сигнатур типів - створювати довільні теореми. Ці теореми дуже корисні, коли ми маємо справу з композиціями чистих функцій. оскільки вони допомагають нам в оптимізації і рефакторінгу нашого коду.
Це наша перша довільна теорема, отримана виключно з сигнатур типів функцій head і map. в якій мовиться: якщо ми зіставимо (map) функцію fn на кожному елементі і потім візьмемо главу (head) результуючого масиву, то це буде еквівалентно застосуванню функції fn на чолі (head) масиву.
Доведемо цю теорему:
Оскільки в загальному сигнатури типів обох функцій однакові, ми можемо зробити висновок, що обидві композиції повертають однаковий результат для однакових вхідних даних.
Вищенаведений висновок спрощений, так як для справжнього виведення довільних теорем будуть потрібні лямбда-обчислення, пояснення яких не є метою даної статті.
Ви завжди можете пробігтися по науковій роботі Вадлера про довільних теоремах. якщо хочете заглибитись.
Зверніть увагу, що функція сompose. використовувана тут, фактично протилежна ідіоматичних compose. Більше інформації тут.
Спасибі за прочитання 💖