Подтвердить что ты не робот

Импорт Haskell имеет побочные эффекты?

Я написал код некоторое время назад, который использует OverloadedStrings для создания ByteString из строковых литералов с шестнадцатеричным кодированием, которые он декодирует, используя функции, предоставляемые base16-bytestring. Это сработало хорошо, но, похоже, я не понял его так хорошо, как я думал.

Вещь, которая меня полностью запутала, такова. Почему

{-# LANGUAGE OverloadedStrings #-}

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

plaintext = "The message" :: B.ByteString

main = print plaintext

скомпилировать и запустить ОК, но если я удалю импорт для 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 не определяет экземпляры typeclass, а только функции encode и decode.

Как этот импорт предоставляет необходимый экземпляр IsString для компиляции кода?

4b9b3361

Ответ 1

В Haskell экземпляры typeclass всегда экспортируются и импортируются - вы не можете их скрыть. Это обычно называют "открытым мировым допущением".

Это означает, что экземпляры typeclass также экспортируются транзитивно: если вы импортируете библиотеку с экземпляром, она также экспортируется из вашего модуля.

В этом случае экземпляр IsString находится в Data.ByteString.Char8, который импортируется Data.ByteString.Base16. Вы должны иметь возможность заменить свой импорт:

import Data.ByteString.Char8 ()

Есть хороший вопрос SO, дающий некоторую информацию о предположении открытого мира, если вы заинтересованы.