Составление функции с помощью Text.Printf.printf
Я хотел бы определить функцию журнала, как
myPutStrLn = putStrLn . (++) "log: "
main = do myPutStrLn "hello"
что хорошо Теперь я хочу отформатировать предоставленную строку с printf
, как это
myPutStrLn $ printf "test %d" (23 :: Int)
Большой! Так как у меня есть этот образец очень часто, я хочу учесть printf
в функцию логгера:
myPrintf = logger . printf
where
-- note, this is just an example. should be
-- replaceable with any function with this
-- typesignature
logger :: String -> IO ()
logger = putStrLn . (++) "log: "
main = myPrintf "test %d" (23 :: Int)
К сожалению, это не с
The function `myPrintf' is applied to two arguments,
but its type `String -> IO ()' has only one
In a stmt of a 'do' block: myPrintf "test %d" (23 :: Int)
In the expression: do { myPrintf "test %d" (23 :: Int) }
In an equation for `main':
main = do { myPrintf "test %d" (23 :: Int) }
GHC выводит myPrintf :: String -> IO ()
, так что, очевидно, что-то не так. Я нашел кое-что о композиции Polyvariadic, но я не могу применить это к моей проблеме. Я даже не уверен, решит ли это мою проблему.
Код также доступен через гист.
1 ответ
Вы можете определить свою функцию, используя hPrintf и дескриптор stdout.
Таким образом, результат функции myPrintf остается экземпляром класса HPrintfType
myPrintf:: (HPrintfType c) => String -> c
myPrintf = (hPrintf stdout) . (printf "log:%s")
main = myPrintf "test %d" (23 :: Int)
Поливариадная форма для функции printf работает только потому, что у вас есть это определение экземпляра:
(PrintfArg a, PrintfType r) => PrintfType (a -> r).
при каждом новом параметре PrintfArg вывод типа возвращает тип класса PrintfType, если это возможно.
Для работы вашей функции регистрации будет иметь следующий тип:
logger :: (PrintfType c) => String -> c
но компилятор потерпит неудачу, потому что функция возвращает IO (), а не более общий класс типов PrintfType.
На мой взгляд, только модификация модуля Text.Printf может помочь вам, потому что вы не можете создать новый экземпляр PrintfType, так как некоторые методы скрыты