Это сложная задача больше, чем полезная проблема (я потратил на нее несколько часов). Учитывая некоторые функции,
put_debug, put_err :: String -> IO ()
put_foo :: String -> StateT [String] m ()
я хочу написать обобщенную функцию printf, назовите ее gprint, чтобы я мог написать
pdebug = gprint put_debug
perr = gprint put_err
pfoo = gprint put_foo
, а затем использовать pdebug
, perr
и ] pfoo
как printf
, например,
pdebug "Hi"
pdebug "my value: %d" 1
pdebug "two values: %d, %d" 1 2
Я не могу придумать достаточно общий класс. Мои попытки были такими (для тех, кто знаком с Printf
или подходом Олега с вариативными функциями)
class PrintfTyp r where
type AppendArg r a :: *
spr :: (String -> a) -> String -> [UPrintf] -> AppendArg r a
или
class PrintfTyp r where
type KRetTyp r :: *
spr :: (String -> KRetTyp r) -> String -> [UPrintf] -> r
Для обоих слишком сложно написать базовые экземпляры: нет хорошего выбора для r
для первого подхода (и его тип не отражен в семействе неинъективных индексированных типов AppendArg
), а во втором подходе заканчивается запись экземпляра PrintfTyp a
, что выглядит неправильно (соответствует слишком большому количеству типов).
Опять же, это просто сложная задача: делайте это, только если это весело. Хотя мне определенно было бы любопытно узнать ответ. Спасибо!!