Так. Це називається "стиль проходження словника". Іноді, коли я роблю якісь особливо складні речі, мені потрібно зібрати клавіатурний клас і перетворити його на словник, оскільки передача словника є більш потужною 1 , але часто досить громіздкою, тому концептуально простий код виглядає досить складно. Я іноді використовую стиль передачі словника іноді на мовах, які не є Haskell, для імітації типів класів (але я дізнався, що це зазвичай не настільки чудова ідея, як це звучить).
Звичайно, щоразу, коли є різниця в виражальній силі, відбувається компроміс. Хоча ви можете використовувати даний API більше способів, якщо він написаний за допомогою DPS, API отримує більше інформації, якщо ви не можете. Один із способів цього виявляється на практиці: це Data.Set
спирається на те, що існує лише один Ord
словник на тип. У Set
магазинах його елементи упорядковано в відповідно до Ord
, і якщо ви будуєте набір з одного словника, а потім вставити елемент , використовуючи іншу, як це було б можливо з DPS, ви можете розбити Set
«s інваріантної і привести до аварії. Цю унікальну проблему можна пом'якшити за допомогою фантомного екзистенціалувведіть для позначення словника, але, знову ж таки, ціною досить прикрої складності в API. Це також відображається приблизно так само в Typeable
API.
Біт унікальності з'являється не дуже часто. У яких класних класах відмінно входить, - це написання коду для вас. Наприклад,
catProcs :: (i -> Maybe String) -> (i -> Maybe String) -> (i -> Maybe String)
catProcs f g = f <> g
який займає два "процесори", які беруть вхід і можуть дати вихід, і об'єднуючи їх, вирівнюючи Nothing
, потрібно було б записати в DPS приблизно так:
catProcs f g = (<>) (funcSemi (maybeSemi listSemi)) f g
По суті, нам довелося прописати тип, який ми використовуємо заново, хоча ми вже прописали його в підписі типу, і навіть це було зайвим, оскільки компілятор вже знає всі типи. Оскільки існує лише один спосіб побудувати заданий Semigroup
тип, компілятор може зробити це за вас. Це має ефект типу "складений інтерес", коли ви починаєте визначати велику кількість параметричних екземплярів і використовуєте структуру своїх типів для обчислення для вас, як у Data.Functor.*
комбінаторах, і це використовується для найкращого ефекту, deriving via
коли ви зможете отримати все "стандартна" алгебраїчна структура вашого типу, написана для вас.
І навіть не запускайте мене на MPTC та фундаменти, які повертають інформацію назад у перевірку типу та висновок. Я ніколи не намагався перетворити таку річ у DPS - я підозрюю, що це передбачає проходження багатьох доказів рівності типу - але в будь-якому випадку я впевнений, що це могло б набагато більше працювати для мого мозку, ніж мені було б зручно з.
-
1 U nless використовувати reflection
в цьому випадку вони стають еквівалентними в силі - але reflection
також може бути обтяжливим для використання.