Есть ли у импорта Haskell побочные эффекты?
Я написал некоторый код некоторое время назад, который использует OverloadedStrings
создавать ByteString
s из шестнадцатеричных строковых литералов, которые он декодирует с использованием функций, предоставляемых base16-bytestring
, Это работало нормально, но, кажется, я не понял это так хорошо, как думал.
То, что меня полностью запутало, так это. Почему
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Base16 ()
import qualified Data.ByteString as B
plaintext = "The message" :: B.ByteString
main = print plaintext
скомпилируйте и запустите OK, но если я удалю импорт для Data.ByteString.Base16
затем он не скомпилируется (похоже на этот вопрос):
test.hs:6:13:
No instance for (Data.String.IsString B.ByteString)
arising from the literal `"The message"'
Согласно Haskell Wiki, такой импорт "полезен только для импорта экземпляров классов типов и ничего больше", но, насколько я вижу, исходный код base16-bytestring не определяет экземпляры классов типов, а только encode
а также decode
функции.
Как импорт обеспечивает необходимый экземпляр IsString
для кода для компиляции?
1 ответ
В Haskell экземпляры классов типов всегда экспортируются и импортируются - их нельзя скрыть. Обычно это называют "предположением об открытом мире".
Это означает, что экземпляры класса типов также экспортируются транзитивно: если вы импортируете библиотеку с экземпляром, она также экспортируется из вашего модуля.
В этом случае IsString
экземпляр находится в Data.ByteString.Char8
, который импортируется Data.ByteString.Base16
, Вы должны иметь возможность заменить ваш импорт:
import Data.ByteString.Char8 ()
Есть хороший вопрос SO, дающий некоторую информацию о предположении открытого мира, если вам интересно.