2011-10-21 86 views
12

爲什麼Haskell的基礎包僅定義IsString類具有從String爲「像字符串」值的轉換,而不是限定的逆變換,從「像字符串」值String爲什麼Data.String.IsString類型類只定義一個轉換?

類應定義爲:

class IsString a where 
    fromString :: String -> a 
    toString :: a -> String 

裁判:http://hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/Data-String.html

+1

我不知道哈斯克爾,但你可能會創建自己的倒數。 – Michael

回答

13

原因是IMHO在於IsString的主要目的是要用於在Haskell源代碼字符串(或(E)的DSL - 也參見Paradise: A two-stage DSL embedded in Haskell)通過OverloadedStrings語言擴展以類似的方式多態文字如何其他工作(例如,通過fromRational浮點文字或fromInteger整數常量)

術語IsString可能會有點誤導,因爲它表明,類型級代表類似字符串的結構,而實際上它只是表示在Haskell源代碼中具有帶引號的字符串表示的類型。

+2

還要注意,像mysql-simple這樣的包中有一些類型使用OverloadedStrings(而不是像QuasiQuotation這樣更安全的方法)來提供更簡單的方法來構造值,但反過來並不總是可能的(或唯一的)。 – ivanm

+0

當我在Aeson上使用OverloadedStrings標誌時,我想到了這個問題,它刪除了所有的包名「name」。但是在另一個上下文中,y已經需要將ByteString解包爲String。 – Zhen

1

如果你想的東西轉換成字符串和反向你應該使用類顯示和閱讀。如果你想在不同的字符串結構之間進行轉換,IsString是你要走的路。這兩種方式都支持轉換,如a-> String和String-> a。

+1

事實上,_not_兩種方式支持轉換像'A - > String'和'字符串 - >了',這是問題的前提。 –

+1

我學習了使用OverloadedStrings的IsString類,它在代碼中確實有很大的幫助。 – Zhen

5

如果你想使用toString :: a -> String,我想你只是忘了show :: a -> String,或更正確Show a => show :: a -> String

如果你想在工作類型均具有一個:: a -> String:: String -> a,你可以簡單地把對這些功能類型類的約束。

doubleConstraintedFunction :: Show a, IsString a => a -> .. -> .. -> a 

我們認真注意,我們避免定義爲一組可也被分成兩個子類的功能型類。因此,我們不會將toString放入IsString

最後,不得不提的還有約Read,它提供了Read a => String -> a。您使用readshow進行非常簡單的序列化。 fromStringIsString都有不同的目的,它是與語言編譯OverloadedStrings有用的,那麼你就可以很方便的插入代碼一樣"This is not a string" :: Text。 (Text是一個(有效)的數據結構絃樂)

+7

用'顯示::顯示一個問題=> A - > String'的是,它不只是進行類型轉換到'String'但同時也增加了報價和字符轉義提供的哈斯克爾語法的字符串表示。因此,'fromString。你似乎暗示'show'不等於'id'。你真的嘗試過你的'backAndForth'函數嗎? – hvr

+0

我沒有建議它是等價的(它不是),我想證明一個函數可以有多個類型約束。但是我意識到'backAndForth'是一個非常具有誤導性的名字,但是我通過代碼中的評論補償了這一點。無論如何,我編輯的帖子更清晰。 – Tarrasch

+0

我也刪除了實現並重命名了這個函數,我同意它最令人困惑。 – Tarrasch

相關問題