У мене немає ні доктора філософії, ні будь-якого іншого ступеня ні в галузі CS, ні математики, ні взагалі ніякої іншої галузі. Я не маю попереднього досвіду роботи зі Scala, ні будь-якою іншою подібною мовою. Я не маю досвіду роботи навіть із системами порівнянного типу. Насправді, єдиною мовою, якою я володію більш ніж просто поверхневими знаннями, про яку навіть є типова система, є Паскаль, не точно відома своєю складною системою типів. (Хоча це дійсно є типи діапазонів, які AFAIK в значній мірі ніякої іншу мову має, але це не зовсім доречним тут.) Решта три мови я знаю, BASIC, Smalltalk і Рубі, жоден з яких навіть є система типу.
І все ж у мене взагалі немає проблем з розумінням підпису map
функції, яку ви опублікували. Мені це здається майже таким самим підписом, який я map
мав у будь-якій іншій мові, яку я коли-небудь бачив. Різниця полягає в тому, що ця версія є більш загальною. Це більше схоже на річ C ++ STL, ніж, скажімо, на Haskell. Зокрема, він абстрагується від конкретного типу збору, вимагаючи лише аргументу IterableLike
, а також абстрагується від конкретного типу повернення, вимагаючи лише існування неявної функції перетворення, яка може побудувати щось із цієї колекції значень результатів. Так, це досить складно, але це насправді лише вираження загальної парадигми загального програмування: не припускайте нічого, чого вам насправді не потрібно.
У цьому випадку, на map
самому ділі не потрібен збір , щоб бути список, або замовленого або бути сортуванням або що - небудь подібне. Єдине, що map
хвилює, це те, що він може отримати доступ до всіх елементів колекції один за одним, але не в конкретному порядку. І не потрібно знати, що являє собою отримана колекція, потрібно лише знати, як її побудувати. Отже, саме цього вимагає підпис його типу.
Отже, замість
map :: (a → b) → [a] → [b]
що є традиційним підписом типу map
, він узагальнений не вимагає конкретної, List
а просто IterableLike
структури даних
map :: (IterableLike i, IterableLike j) ⇒ (a → b) → i → j
який далі узагальнюється, вимагаючи лише існування функції, яка може перетворити результат у ту структуру даних, яку бажає користувач:
map :: IterableLike i ⇒ (a → b) → i → ([b] → c) → c
Я визнаю, що синтаксис трохи незграбний, але семантика однакова. В основному, це починається з
def map[B](f: (A) ⇒ B): List[B]
що є традиційним підписом для map
. (Зверніть увагу, як через об'єктно-орієнтований характер Scala параметр списку вхідних даних зникає, оскільки це тепер неявний параметр приймача, який має кожен метод в системі одноосібної передачі OO.) Потім він узагальнився від конкретного List
до більш загальногоIterableLike
def map[B](f: (A) ⇒ B): IterableLike[B]
Тепер він замінює IterableLike
збір результатів функцією, яка виробляє , ну, практично майже все.
def map[B, That](f: A ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That
Що я дійсно вважаю , це не що важко зрозуміти. Насправді вам потрібна лише пара інтелектуальних інструментів:
- Вам потрібно знати (орієнтовно), що
map
таке. Якби ви дали лише підпис типу без назви методу, я визнаю, було б набагато важче зрозуміти, що відбувається. Але оскільки ви вже знаєте, що map
слід робити, і ви знаєте, яким повинен бути підпис його типу, ви можете швидко просканувати підпис і зосередитись на аномаліях, наприклад "чому це map
приймає дві функції як аргументи, а не одну?"
- Вам потрібно вміти фактично читати підпис типу. Але навіть якщо ви ніколи раніше не бачили Scala, це повинно бути досить легко, оскільки це справді лише суміш синтаксисів типів, які ви вже знаєте з інших мов: VB.NET використовує квадратні дужки для параметричного поліморфізму та за допомогою стрілки для позначення тип повернення та двокрапка для відокремлення назви та типу, насправді є нормою.
- Вам потрібно приблизно знати, про що йдеться в загальному програмуванні. (Який не , що важко зрозуміти, так як це в основному все прописано в назві: це буквально тільки програмування в загальному вигляді).
Жоден із цих трьох не повинен завдавати серйозного головного болю жодному професійному або навіть хобі-програмісту. map
була стандартною функцією майже в усіх мовах, розроблених за останні 50 років, той факт, що різні мови мають різний синтаксис, повинен бути очевидним для всіх, хто створив веб-сайт з HTML та CSS, і ви не можете підписатися на навіть віддалене програмування пов’язаний розсилка з розсилкою, не маючи прикрого фанатика C ++ з церкви святого Степанова, що пояснює чесноти родового програмування.
Так, Скала є складною. Так, Scala має одну з найскладніших типів, відому людині, яка конкурує і навіть перевершує такі мови, як Haskell, Miranda, Clean або Cyclone. Але якби складність була аргументом проти успіху мови програмування, C ++ давно б помер, і ми всі писали схему. Є багато причин, чому Scala, швидше за все, не буде успішною, але той факт, що програмістам не вдається увімкнути мозок перед тим, як сісти перед клавіатурою, напевно, не буде головним.