TL;DR:
プレリュードの方法をコピーしshowList_
、クラス関数として使用してリストのインスタンスを生成し、String の定義をオーバーライドできるようにします。
警告
記録として、newtype ラッパーを使用したwowofbob の回答は、私が実生活で使用するシンプルでクリーンなソリューションですが、Prelude がこれをどのように行うかについてもいくつか見ることは有益だと感じました。
デフォルトでコンマを挿入する
プレリュードでこれを行う方法は、Show
クラスにリストを表示する関数を持たせ、オーバーライドできるデフォルトの定義を持たせることです。
import Data.List (intercalate)
intercalate :: [a] -> [[a]] -> [a]
間にコンマを入れるために使用します:
ghci> intercalate "_._" ["intercalate","works","like","this"]
"intercalate_._works_._like_._this"
showList_ クラス関数を作成し、デフォルトでカンマ区切りのリストを表示します。
したがって、showList
関数のデフォルトの実装を持つクラスと、重要なことにshow_
、通常のshow
関数を使用するだけのデフォルトの実装を持つクラスです。それを使用できるようにするには、型が既に型クラスにあると主張する必要がありますが、Show
私が理解している限り、それは問題ありません。
class Show a => Show_ a where
show_ :: a -> String
showList_ :: [a] -> String
show_ = show
showList_ xs = '[' : intercalate ", " (map show_ xs) ++ "]"
実際の Show クラスは、効率上の理由から直接ではString -> String
なく type の関数を使用し、括弧の使用を制御する優先順位引数を使用しますが、簡単にするためにすべてスキップします。String
リストのインスタンスを自動的に作成する
これで、関数を使用しshowList
てリストのインスタンスを提供できます。
instance Show_ a => Show_ [a] where
show_ xs = showList_ xs
Show a =>
スーパークラスはインスタンスを非常に簡単にします
ここで、いくつかの例に行き着きます。デフォルトのshow_
実装のため、デフォルトをオーバーライドする必要がない限り、実際のプログラミングを行う必要はありません。これは Char に対して行いますString ~ [Char]
。
instance Show_ Int
instance Show_ Integer
instance Show_ Double
instance Show_ Char where
show_ c = [c] -- so show_ 'd' = "d". You can put show_ = show if you want "'d'"
showList_ = id -- just return the string
実際には:
デフォルトの関数が使用される"
ため、ghci の出力から非表示にするのはあまり役に立ちませんが、 を使用すると、引用符が消えます。show
putStrLn
put :: Show_ a => a -> IO ()
put = putStrLn . show_
ghci> show "hello"
"\"hello\""
ghci> show_ "hello"
"hello"
ghci> put "hello"
hello
ghci> put [2,3,4]
[2, 3, 4]
ghci>