Как написать семейство функций printf (отладочная печать и т. Д.) На Haskell

Это сложная задача больше, чем полезная проблема (я потратил на нее несколько часов). Учитывая некоторые функции,

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 , что выглядит неправильно (соответствует слишком большому количеству типов).

Опять же, это просто сложная задача: делайте это, только если это весело. Хотя мне определенно было бы любопытно узнать ответ. Спасибо!!

5
задан gatoatigrado 5 March 2012 в 07:27
поделиться