Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
data BaconBox = (Tossable a) => BaconBox String a
BaconBox "bool.and" ["x", "y"] doAnd
data BaconBox = forall a. (Tossable a) => BaconBox String a
toss :: [String] -> IO String
toss [] f = fmap show f
toss :: [String] -> t -> IO String, проглядел-с.О, сколько нам открытий чудных :-P
[a] -> IO a.BaconBox после того, как вы ввели тип Tossable? Почему не [Tossable]?Map String BaconBox или ассоциативный список, но я решил держать метаданные метода вместе. Может пригодится для, например, автоматической генерации документации сервиса. Да и обычно методов не так много, чтобы O(n) (в худшем случае) поиск по списку был настолько прям медленней.data MetaData meta obj = MetaData meta obj
f :: a -> b -> ... -> r
f :: [String] -> String
Удаление String из BaconBox не помешает держать метаданные с объектом — вы же можете создать тип:
И это я бы рассматривал отдельно от вашей предметной области, и вынес бы этот код в отдельный модуль.
И еще, можно не IO использовать, а просто некую монаду, и тогда изменяя ее, можно будет по разному обрабатывать ошибки, так как будет подставляться разная функция fail.
(Monad m, Show a) => m a и, завернув в Identity, получить диспетчеризацию для чистых функций.Но это не совсем то. Но и не совсем не то! awesome.gif
Тут фиксируется класс входных аргументов, гарантирующий [s]успешность[/s] наличие десерилизатора для типа
Картинки не грузятся.
[s]успешность[/s]
Священный грааль динамической диспетчеризации