unicode - 如何破解 GHCi(或 Hugs)以便打印未转义的 Unicode 字符?

看问题:通常,在交互式 Haskell 环境中,非拉丁 Unicode 字符(构成结果的一部分)被转义打印,即使语言环境允许此类字符(与通过 putStrLn 直接输出相反, putChar 看起来不错且可读)--示例显示 GHCi 和 Hugs98:

$ ghci
GHCi, version 7.0.1: http://www.haskell.org/ghc/  :? for help
Prelude> "hello: привет"
"hello: \1087\1088\1080\1074\1077\1090"
Prelude> 'Я'
'\1071'
Prelude> putStrLn "hello: привет"
hello: привет
Prelude> :q
Leaving GHCi.
$ hugs -98
__   __ __  __  ____   ___      _________________________________________
||   || ||  || ||  || ||__      Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__||  __||     Copyright (c) 1994-2005
||---||         ___||           World Wide Web: http://haskell.org/hugs
||   ||                         Bugs: http://hackage.haskell.org/trac/hugs
||   || Version: September 2006 _________________________________________

Hugs mode: Restart with command line option +98 for Haskell 98 mode

Type :? for help
Hugs> "hello: привет"
"hello: \1087\1088\1080\1074\1077\1090"
Hugs> 'Я'
'\1071'
Hugs> putStrLn "hello: привет"
hello: привет

Hugs> :q
[Leaving Hugs]
$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$ 

我们可以猜测这是因为 printshow 用于格式化结果,并且这些函数尽最大努力以规范、最大可移植的方式格式化数据——所以他们更喜欢转义奇怪的字符(也许是甚至在 Haskell 的标准中都有说明):

$ ghci
GHCi, version 7.0.1: http://www.haskell.org/ghc/  :? for help
Prelude> show 'Я'
"'\\1071'"
Prelude> :q
Leaving GHCi.
$ hugs -98
Type :? for help
Hugs> show 'Я'
"'\\1071'"
Hugs> :q
[Leaving Hugs]
$ 

但是,如果我们知道如何破解 GHCi 或 Hugs 以人类可读的方式打印这些字符,即直接,未转义,那就太好了。在将交互式 Haskell 环境用于教育目的时,您可以在非英语观众面前进行 Haskell 教程/演示,您希望在他们的人类语言中展示一些有关数据的 Haskell。

实际上,它不仅可用于教育目的,还可用于调试!当您有在表示其他语言单词的字符串上定义的函数时,使用非 ASCII 字符。因此,如果程序是特定于语言的,并且只有另一种语言的词作为数据才有意义,并且您的函数仅在这些词上定义,那么在 GHCi 中调试时查看这些数据很重要。

总结一下我的问题:有哪些方法可以破解现有的交互式 Haskell 环境,以便在结果中更友好地打印 Unicode? (在我的情况下,“更友好”意味着“更简单”:我希望 GHCi 或 Hugs 中的 print 以简单直接的方式显示非拉丁字符,如 putCharputStrLn 所做的那样,即未转义。)

(也许,除了 GHCi 和 Hugs98 之外,我还会看看现有的 Emacs 与 Haskell 交互的模式,看看它们是否可以以漂亮的、未转义的方式呈现结果。)

最佳答案

破解此问题的一种方法是将 GHCi 包装到 shell 包装器中,该包装器读取其标准输出并取消转义 Unicode 字符。这当然不是 Haskell 的方式,但它可以完成工作:)

例如,这是一个使用 shpython3 的包装器 ghci-esc(这里 3 很重要):

#!/bin/sh

ghci "$@" | python3 -c '
import sys
import re

def tr(match):
    s = match.group(1)
    try:
        return chr(int(s))
    except ValueError:
        return s

for line in sys.stdin:
    sys.stdout.write(re.sub(r"\\([0-9]{4})", tr, line))
'

ghci-esc的用法:

$ ./ghci-esc
GHCi, version 7.0.2: http://www.haskell.org/ghc/  :? for help
> "hello"
"hello"
> "привет"
"привет"
> 'Я'
'Я'
> show 'Я'
"'\Я'"
> :q
Leaving GHCi.

请注意,并非上述所有取消转义都正确完成,但这是向观众展示 Unicode 输出的快速方法。

https://stackoverflow.com/questions/5535512/

相关文章:

android - 在 android textview 中显示