19

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'

何か案は?

編集済み

示唆されたように、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 を使用するというすべてのアドバイスを考えると、これがそのままでは機能しないのは驚くべきことです。

4

4 に答える 4

13

警告: テキスト形式は維持されておらず、著者から 2 年間応答がありません。他の回答を参照してください。


テキスト形式のパッケージを見てみましょう。これは に似ていますがText.Printf、 のために特別に設計されていData.Text.Lazyます。

に比べて、テキスト形式には他にもいくつかの利点がありますText.Printf

  • このBuildableクラスは公開されているため、新しいパラメーターの型をサポートするように拡張できます。
  • Text.Printf戻り値へのアクセスに関する問題を回避する、varargs へのより単純なアプローチを使用します。
  • いくつかの理由により、はるかに高速になるはずです。
    • String非効率的な表現に変換されることはありません。
    • UPrintfとは異なり、中間データ型を構築しませんText.Printf
    • レンダリングとに二重変換パッケージを使用します。これは、Prelude の方法よりも約30 倍高速です。DoubleFloat
于 2012-06-09T23:27:44.757 に答える
3

この質問が出されて以来、basetextライブラリはこれをサポートするように更新されました。base >= 4.7.0.0およびtext >= 1.2.2.0の場合、OP の MWE は実際に機能します。

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Text
import Text.Printf

main :: IO ()
main = do
  let input :: Text = "abc"
  printf "Input: %s\n" input

出力:

$ ghci
GHCi, version 8.2.2: http://www.haskell.org/ghc/  :? for help
Prelude> :l test.hs
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, one module loaded.
*Main> main
Input: abc
*Main> 
Leaving GHCi.
于 2018-06-27T07:32:20.593 に答える
1

ドキュメントから:

HPrintfType クラスは、hPrintf の可変引数マジックを提供します。その実装は、意図的にこのモジュールからは見えません。

TH を使用して HPrintfType インスタンスを生成できますが (TH はエクスポート制限を無視するため)、最も簡単な解決策はおそらくprintf'型関数です。

printt :: PrintType r => Text -> r
printt = printf . Data.Text.unpack
于 2012-06-09T20:53:51.450 に答える
1

チェックアウトする価値のある別のパッケージ:フォーマット

テキスト用のコンビネータベースの型保証フォーマット (printf() や FORMAT など)。

例:

format ("Person's name is " % text % ", age is " % hex) "Dave" 54
于 2016-11-02T11:37:42.293 に答える