2013-02-02 18 views
24

Ich schrieb vor einiger Zeit einen Code, der OverloadedStrings verwendet, um ByteString s aus Hex-codierten String-Literalen zu erstellen, die es mit den Funktionen von base16-bytestring dekodiert. Das hat gut funktioniert, aber es scheint, dass ich es nicht so gut verstanden habe, wie ich dachte.Haben Haskell-Importe Nebenwirkungen?

Die Sache, die mich völlig verwirrt hat, ist dies. Warum funktioniert

{-# LANGUAGE OverloadedStrings #-} 

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

plaintext = "The message" :: B.ByteString 

main = print plaintext 

kompilieren und ausführen OK, aber wenn ich den Import für Data.ByteString.Base16 entfernen dann scheitert es zu kompilieren (ähnlich this question):

test.hs:6:13: 
No instance for (Data.String.IsString B.ByteString) 
    arising from the literal `"The message"' 

Nach dem Haskell Wiki, ein Import wie dies "Das ist nützlich, um nur Instanzen von typeclasses und nichts anderes zu importieren", aber soweit ich sehen kann, definiert der Quellcode von base16-bytestring keine typeclass-Instanzen, sondern nur die Funktionen encode und decode.

Wie stellt der Import die erforderliche Instanz von IsString für den zu kompilierenden Code bereit?

Antwort

32

In Haskell werden Typklasseninstanzen immer exportiert und importiert - Sie können sie nicht ausblenden. Dies wird üblicherweise als "Open-World-Annahme" bezeichnet.

Dies bedeutet, dass Typklasseninstanzen auch transitiv exportiert werden: Wenn Sie eine Bibliothek mit einer Instanz importieren, wird sie auch von Ihrem Modul exportiert.

In diesem Fall ist die IsString Instanz in Data.ByteString.Char8, die von Data.ByteString.Base16 importiert wird. Sie sollten Ihren Import mit ersetzen können:

import Data.ByteString.Char8() 

Es gibt eine schönes SO question einige Informationen über die offene Welt Annahme geben, wenn Sie interessiert sind.

Verwandte Themen