Светият Граал на динамичното изпращане

Голямата неприятност Тесното място при статичното писане е разнородни колекции и вариадични функции. Следователно, в RPC библиотеките често има подход, когато входящите данни се намират в едно ADT парче, а за методите има един и същ плосък тип "[Foo] -> IO Foo", чиито изпълнения десериализиране/сериализиране на copy-paste, което е неудобно и поражда грешки, вкл. време на изпълнение.

Решението на този проблем ме притесни почти от самото начало на практическото ми приложение на Haskell и накрая, снощи, вдъхновението ме навлезе на цели 6,5 милиолеги и след сесия за гадаене и разговор с ghci, всичко работи за мен.

светият

Да кажем, че искаме да направим списък/речник Текст -> Метод. И веднага ужас:

Всички методи са от различен тип. Това може да бъде решено чрез поставянето им в непрозрачна кутия.

Но такава кутия не може да бъде разопакована, защото не е ясно какво изобщо може да се направи с тях чрез разопаковане. Това означава, че имате нужда от клас типове, които могат да бъдат в него и описващи как да приведете функцията в нормалния й вид, т.е. функции, готови да десериализират входните данни и да сериализират резултата.

В този пример ще се използва „Протокол“ за четене/показване. Не е най-доброто, но за останалото е същото. Типът данни, съответно, ще бъде String.

С такава дефиниция вече е ясно дори на компилатора, че всеки тип може да се постави вътре в полето, за което е дефинирана функцията за хвърляне, което ... Бах! Тук плавно преминаваме към втория проблем. В края на краищата искате извиканите методи да могат да имат всякакви аргументи и във всяко количество. Тези. така че в полето можете просто да вземете и поставите всеки RPC манипулатор, за който са дефинирани рутинни процедури.