Есть ли у импорта 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, дающий некоторую информацию о предположении открытого мира, если вам интересно.

Другие вопросы по тегам