2012-08-27 8 views
6

私がよく知っているほとんどのオブジェクト指向言語では、StringtoStringメソッドは、実際には唯一の識別関数です。しかし、ハスケルではshow二重引用符を追加します。クォートを追加しない多相の `toString`関数はありますか?

だから私はこの

f :: Show a => [a] -> String 
f = concat . map show 

のような関数の何かを書く場合に予想されるとして、それは数字

f [0,1,2,3] -- "0123" 

のために動作しますが、とき、本当に私の文字列は、余分な引用符で

f ["one", "two", "three"] -- "\"one\"\"two\"\"three\"" 

を終わります欲しいものは"onetwothree"です。

多態的にfと書いたければ、Showという制約でそれを行い、文字列のShowインスタンスをオーバーライドしないでください(それが可能であれば)。

class (Show a) => ToString a where 
    toString = show 

、すべてのインスタンスを追加します。

私が思い付くことができる最高のは、私自身の型クラスを作成するのですか?

instance ToString String where toString = id 
instance ToString Char where toString = pure 
instance ToString Int 
instance ToString Maybe 
...etc 
+0

'newtype'構造を使って、' 'LiteralString'](https://github.com/corsis/PortFusion/blob/ad63a006cff324667cca2316699e26a0078fbc02/src/Main.hs#L67)のタイプを作成しました。 'と' Read'インスタンス:https://github.com/corsis/PortFusion/blob/ad63a006cff324667cca2316699e26a0078fbc02/src/Main.hs#L67 –

+0

も参照してくださいhttp://stackoverflow.com/questions/12102874/haskell-suppress-quotes -around-strings-shown-shown – sth

+0

'Show'は二重引用符を追加するだけでなく、また、改行などの文字をエスケープします。たとえば、1文字の文字列 '' \ n "'は4文字の文字列で表示され、文字 "、\、n"で示されます。 – sdcvvc

答えて

3

あなたはこれを行うことができます。これはおそらく恐ろしい考えであることを

{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-} 

class Show a => ToString a where 
    toString :: a -> String 

instance Show a => ToString a where 
    toString = show 

instance ToString String where 
    toString = id 

Prelude> toString "hello" 
"hello" 
Prelude> toString 3 
"3" 

注意。

+0

ありがとうございます。私は特にあなたの最終的な言葉を楽しんだ "これはおそらくひどい考えであることに注意してください。 :)これを可能にするために、さまざまな言語拡張が実際に何をしているのか説明できますか? –

+3

'FlexibleInstances'がなければ、裸型変数を型クラスのメンバーとして立てることはできません。 'UndecidableInstances'がなければ、少なくとも1つのインスタンスの型引数はベア型変数であってはいけません。これらのいずれかを持たないと、上記の最初のインスタンス宣言が許可されません。明らかに最初のインスタンスがすべての表示可能な型に適用されるので、 'OverlappingInstances'がなければ、上記の両方のインスタンスを一緒に持つことはできません。' String'はそのような型です。 –

+0

インスタンスが他のモジュールに漏洩する可能性があるという問題は、(おそらく)ひどい考えですか? –

2

あなたはOverloadedStringsnewtypeを使用することができます。

{-# LANGUAGE OverloadedStrings #-} 

import   Data.ByteString.Char8  (ByteString) 
import qualified Data.ByteString.Char8 as B 

newtype LiteralString = LS ByteString 
instance IsString LiteralString where fromString = LS . B.pack 
instance Show  LiteralString where show (LS x) = B.unpack x 
instance Read  LiteralString where readsPrec p s = map (\(!s, !r) -> (LS s,r)) $! readsPrec p s 

hello :: LiteralString 
hello = "hello world" 

main :: IO() 
main = putStrLn . show $! hello 

出力:

hello world 

背中で示す文字列を読み込むときに、通常の場合は二重引用符は、実際に便利ですより大きな表現のコンテキストは、文字列の値を値から明確に区切ります他に示すタイプの:

x :: (ByteString, Int) 
x =  read . show $! ("go", 10) 
-- string value starts --^^-- ends 

y :: (LiteralString, Int) 
y =  read . show $! ("go", 10) 
-- string value starts --^  ^consumes all characters; read fails 
+0

私はそれの主な問題は、それがまだ知っている関数の呼び出し元に依存しているということだと思います非標準のString型を使用する必要があります。 –

+3

私は、 'show'の主な問題は、かなりの印刷/解析目的のためにそれらを使うことに対して人々が言うかもしれないにもかかわらず、' read'との強力な結合であると思います。 'readのデフォルト動作show = id'とそれは二重引用符の理由と思われます。 –

5

Prettyクラスとそれに対応するタイプDocはショーのために必要な行動を持っています。ただし、リンクによって異なるユースケースが示されます。多分あなたはその質問を編集できますか?

+0

ありがとう、私はこのクラスについて知りませんでした。 –

7

あなたの問題の根本的な原因は、showは実際にはrenderToTextではないと思います。 Haskellのコードに貼り付けて同じ値を取得するか、readを使って同じ値に戻すことができるテキストを生成するはずです。

このため、show "1" = "1"show 1 = "1"は情報を失うため、show "foo" = "foo"は機能しません。

あなたは"foo"1には、取得するために取得する"foo"には適用することができるようにしたい操作が"1"show以外のものです。 showはJava-esqueではありませんtoString

私がこれを必要としていたとき、私は自分の新しいタイプのクラスを作って、そのインスタンスをたくさん作って、それをShowではなく使っていました。ほとんどのインスタンスはshowで実装されていましたが、Stringは私がカスタマイズしたい唯一のものではありませんでしたので、別のタイプのクラスが完全に無駄にならないようにしました。実際には、実際にインスタンスが必要な型はほんの一握りであることがわかりました。コンパイルエラーが発生したときにそれらを追加するのはかなり簡単でした。

+0

ベン、あなたの答えは正確ではありません。 'Show'の目的は、Haskellの値を文字列にレンダリングすることです。同形Read/Showインスタンスを持つ義務はありません - Haskell Reportを参照してください。確かに同形Read/Showインスタンスは便利ですが、必須ではありません。シリアライズしたい場合は、代わりに 'Binary'を使うことを検討してください。 –

+1

それは本当ですが、標準のライブラリインスタンス(および 'deriving 'によって生成されたインスタンス)がすべてHaskell構文を使用することを考えると、' show'生成文字列の対象読者はHaskellプログラマです。 「この値のテキストをフォーマットしてユーザに表示できる」ためのものではありません。 – Ben

関連する問題