2013-02-02 14 views
24

Napisałem jakiś kod jakiś czas temu, który używa OverloadedStrings do utworzenia ByteString s z literałów String zakodowanych w kodzie, które dekoduje za pomocą funkcji dostarczonych przez base16-bytestring. To działało dobrze, ale wydaje mi się, że nie rozumiałem tego tak dobrze, jak myślałem.Czy import Haskell ma skutki uboczne?

To, co mnie całkowicie zdezorientowało, to jest to. Dlaczego

{-# LANGUAGE OverloadedStrings #-} 

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

plaintext = "The message" :: B.ByteString 

main = print plaintext 

skompilować i uruchomić OK, ale jeśli usunąć import do Data.ByteString.Base16 to nie skompilować (podobny do this question):

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

Według Haskell Wiki, import, jak to jest "przydatne tylko do importowania wystąpień typów liter i niczego innego", ale o ile widzę, kod źródłowy baz16-bytestring nie definiuje żadnych wystąpień typu -tablica, tylko funkcje encode i decode.

W jaki sposób import zapewnia niezbędną instancję IsString dla kodu do kompilacji?

Odpowiedz

32

W Haskell instancje z typeclass są zawsze eksportowane i importowane - nie można ich ukryć. Zwykle jest to nazywane "założeniem otwartego świata".

Oznacza to, że instancje klasy komputerowej są również eksportowane tranzytowo: jeśli importujesz bibliotekę z instancją, zostanie ona również wyeksportowana z twojego modułu.

W tym przypadku instancja IsString znajduje się w Data.ByteString.Char8, która jest importowana przez Data.ByteString.Base16. Powinieneś być w stanie zastąpić import z:

import Data.ByteString.Char8() 

Jest miły SO question podając pewne informacje na otwartym światem założeniu, jeśli jesteś zainteresowany.

Powiązane problemy