【问题标题】:Haskell IO with non English characters非英文字符的 Haskell IO
【发布时间】:2010-08-31 17:38:47
【问题描述】:

看看这个,我试试

appendFile "out" $ show 'д'

'д' 是俄语字母中的字符。 之后“out”文件包含:

'\1076'

我的理解是字符“ä”的 unicode 数字代码。为什么会这样?我怎样才能得到我的角色的正常表现?

有关其他信息,它很好用:

appendFile "out"  "д"

谢谢。

【问题讨论】:

    标签: unicode haskell localization io locale


    【解决方案1】:

    show 会转义 ASCII 范围之外的所有字符(以及 ASCII 范围内的一些字符),所以不要使用show

    由于“д”可以正常工作,因此请使用它。如果你不能因为 ä 实际上在一个变量中,你可以使用 [c] (其中 c 是包含字符的变量。如果你需要用单引号括起来(就像 show 一样),你可以使用 @987654324 @。

    【讨论】:

    • 我认为 show 被许多 Haskell 程序员过度使用。它不适合漂亮的打印,因为它用于序列化(例如read . show 应该等于id),但是对于大多数序列化应用程序来说性能太差了。它对于测试和原型设计很方便,但除此之外,我会三思而后行使用show
    • 我想用 show 来调试。 “show”将“数据结构”转换为字符串。例如,我有 [(String,String)] 并且我希望看到它。当然最好的方法是输出到控制台但这是不可能的。因为我使用文件。
    • 我同意调试是表演最常见的用途之一。由于在 ASCII 之外转义字符(以及转义换行符,这对我来说特别烦人),因此对于像您这样的情况来说,这会变得很棘手。
    【解决方案2】:

    阅读您对我的评论的回复后,我认为您的情况是您有一些数据结构,可能类型为[(String,String)],并且您想将其输出以进行调试。使用 show 会很方便,但它会转义非 ASCII 字符。

    这里的问题不在于 unicode,您需要一个能够正确格式化数据以供显示的函数。我不认为show 是正确的选择,部分原因是转义某些字符的问题。您需要的是一个像Show 这样的类型类,但它显示用于读取的数据而不是转义字符。也就是说,您需要一个漂亮的打印机,它是一个提供格式化数据以供显示的函数的库。 Hackage 上有几款漂亮的打印机,我先看看uulibwl-pprint。我认为这两种方法都适合,无需太多工作。

    这是一个使用 uulib 工具的示例。使用 Pretty 类型类代替 Show,该库带有许多有用的实例。

    import UU.PPrint
    
    -- | Write each item to StdOut
    logger :: Pretty a => a -> IO ()
    logger x = putDoc $ pretty x <+> line
    

    在 ghci 中运行:

    Prelude UU.PPrint> logger 'Д'
    Д 
    Prelude UU.PPrint> logger ('Д', "other text", 54)
    (Д,other text,54) 
    Prelude UU.PPrint> 
    

    如果要输出到文件而不是控制台,可以使用hPutDoc 函数输出到句柄。您也可以调用renderSimple 来生成SimpleDoc,然后在构造函数上进行模式匹配以处理输出,但这可能更麻烦。不管你做什么,避免show

    Prelude UU.PPrint> show $ pretty 'Д'
    "\1044"
    

    您还可以编写自己的类型类,类似于 show,但可以根据需要进行格式化。如果你走这条路,Text.Printf 模块会很有帮助。

    【讨论】:

    • 你能告诉我漂亮的打印机如何帮助我吗
    • 我添加了一个示例,应该可以清楚地说明这一点。请注意,使用漂亮打印机的常用方法是一次组装所有数据并一次性渲染文档。我已经逐行完成了,因为这对调试更有用;您将在程序崩溃或挂起时获得更多部分输出。
    【解决方案3】:

    使用数据.文本。它为 IO 提供了区域感知和编码支持。

    【讨论】:

    • Data.Text 很棒,但是内置的 IO 系统也提供了区域感知和编码支持(从 GHC 6.12 开始)。
    【解决方案4】:

    “UTF Haskell”的快速网络搜索应该会为您提供良好的链接。可能最推荐的包是text 包。

    import Data.Text.IO as UTF
    import Data.Text as T
    
    main = UTF.appendFile "out"  (T.pack "д")
    

    【讨论】:

      【解决方案5】:

      要按节目显示国家字符,请输入您的代码:

      {-# LANGUAGE FlexibleInstances #-}
      
      instance {-# OVERLAPPING #-} Show String where
          show = id
      

      那你可以试试:

      *Main> show "ł"
      ł
      *Main> show "ą"
      ą
      *Main> show "ę"
      ę
      *Main> show ['ę']
      ę
      *Main> show ["chleb", "masło"]
      [chleb,masło]
      *Main> data T = T String deriving (Show)
      *Main> t = T "Chleb z masłem"
      *Main> t
      T Chleb z masłem
      *Main> show t
      T Chleb z masłem
      

      【讨论】:

        【解决方案6】:

        我之前的解决方案中没有引号。另外,我现在把代码放到模块里,模块必须要导入到你的程序中。

        {-# LANGUAGE FlexibleInstances #-}
        
        module M where
        
        instance {-# OVERLAPPING #-} Show String where
            show x = ['"'] ++ x ++ ['"']
        

        初学者须知:请记住该节目不显示任何内容。 show 将数据转换为带有其他格式字符的字符串。

        我们可以在 WinGHCi 中尝试: 由 WinGHCi 自动生成

        *M> "ł"
        "ł"
        *M> "ą"
        "ą"
        *M> "ę"
        "ę"
        *M> ['ę']
        "ę"
        *M> ["chleb", "masło"]
        ["chleb","masło"]
        *M> data T = T String deriving (Show)
        *M> t = T "Chleb z masłem"
        

        或手动

        *M> (putStrLn . show) "ł"
        "ł"
        *M> (putStrLn . show) "ą"
        "ą"
        *M> (putStrLn . show) "ę"
        "ę"
        *M> (putStrLn . show) ['ę']
        "ę"
        *M> (putStrLn . show) ["chleb", "masło"]
        ["chleb","masło"]
        *M> data T = T String deriving (Show)
        *M> t = T "Chleb z masłem"
        *M> (putStrLn . show) t
        T "Chleb z masłem"
        

        在要显示的代码中:

        putStrLn "ł"
        putStrLn "ą"
        putStrLn "ę"
        putStrLn "masło"
        (putStrLn . show) ['ę']
        (putStrLn . show) ["chleb", "masło"]
        data T = T String deriving (Show)
        t = T "Chleb z masłem"
        (putStrLn . show) t
        

        我正在为 Google 添加标签“polskie znaki haskell”。

        【讨论】:

        • 代码 T "Chleb z masłem" 中的最后一行是错误的。不要使用它。
        猜你喜欢
        • 1970-01-01
        • 2016-10-08
        • 2011-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-01
        • 2011-09-17
        相关资源
        最近更新 更多