我厌倦了在打印出来进行调试之前一直解压缩Data.Text
个实例,并认为只需使用Text.Printf
。不幸的是,我无法让它发挥作用:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Text
import Text.Printf
--instance PrintfArg Text where
-- toUPrintf = toUPrintf . unpack
main :: IO ()
main = do
let input :: Text = "abc"
printf "Input: %s\n" input
错误:
src/Main.hs:12:3:
No instance for (PrintfArg Text)
arising from a use of `printf'
Possible fix: add an instance declaration for (PrintfArg Text)
In a stmt of a 'do' block: printf "Input: %s" input
In the expression:
do { let input :: Text = "abc";
printf "Input: %s" input }
In an equation for `main':
main
= do { let input :: Text = ...;
printf "Input: %s" input }
取消注释实例声明后:
src/Main.hs:7:7:
`toUPrintf' is not a (visible) method of class `PrintfArg'
src/Main.hs:7:19: Not in scope: `toUPrintf'
有什么想法吗?
EDITED
正如所建议的那样,试过TH,仍然没有去:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
import Data.Text
import Language.Haskell.TH
import Text.Printf
runQ [d| instance PrintfArg Text where toUPrintf = toUPrintf . unpack|]
main :: IO ()
main = do
let input :: Text = "abc"
printf "Input: %s\n" input
错误:
src/Main.hs:9:40:
'toUPrintf' is not a (visible) method of class 'PrintfArg'
src/Main.hs:9:52: Not in scope: 'toUPrintf'
帮助!令人惊讶的是,根据默认使用Data.Text的所有建议,这不是开箱即用的。
答案 0 :(得分:13)
警告:文本格式未维护,作者在2年内没有回复。请参阅其他答案。
我会查看text-format包:它类似于Text.Printf
,但专为Data.Text.Lazy
而设计。
文本格式还有一些优于Text.Printf
的优点:
Buildable
类,因此可以扩展它以支持新的参数类型。Text.Printf
accessing the return value中的问题。String
表示; Text.Printf
中的UPrintf
不同; Double
和Float
,这比Prelude的方法大约30 times faster。答案 1 :(得分:1)
来自文档:
HPprintfType类为hPrintf提供变量参数magic。它的实现有意在本模块中看不到。
虽然您可以使用TH生成HPrintfType实例(因为TH忽略了导出限制),但最简单的解决方案可能是printf'
类型函数:
printt :: PrintType r => Text -> r
printt = printf . Data.Text.unpack
答案 2 :(得分:1)
另一个值得一试的套餐:formatting
基于组合器的类型安全格式(如printf()或FORMAT),用于Text。
示例:
format ("Person's name is " % text % ", age is " % hex) "Dave" 54
答案 3 :(得分:1)
自从提出此问题以来,$cutend-1
和base
库已更新为支持此问题。如果您具有 base> = 4.7.0.0 和 text> = 1.2.2.0 ,则OP的MWE实际上可以工作:
text
输出:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Text
import Text.Printf
main :: IO ()
main = do
let input :: Text = "abc"
printf "Input: %s\n" input