online - haskell pdf
¿Las importaciones de Haskell tienen efectos secundarios? (1)
Hace un tiempo escribí un código que utiliza OverloadedStrings
para crear ByteString
a partir de literales String codificados en hexadecimal, que decodifica utilizando las funciones proporcionadas por base16-bytestring
. Esto funcionó bien, pero parece que no lo entendí tan bien como pensaba.
Lo que me tiene completamente confundido es esto. Por que
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Base16 ()
import qualified Data.ByteString as B
plaintext = "The message" :: B.ByteString
main = print plaintext
compile y ejecute OK, pero si Data.ByteString.Base16
la importación para Data.ByteString.Base16
entonces falla la compilación (similar a esta pregunta ):
test.hs:6:13:
No instance for (Data.String.IsString B.ByteString)
arising from the literal `"The message"''
De acuerdo con Haskell Wiki , una importación como esta es "útil solo para importar instancias de typeclasses y nada más", pero, por lo que puedo ver, el código fuente de base16 no define ninguna instancia de typeclass, solo la encode
y funciones de decode
.
¿Cómo proporciona la importación la instancia necesaria de IsString
para que el código se compile?
En Haskell, las instancias de typeclass siempre se exportan e importan, no se pueden ocultar. Esto generalmente se conoce como el "supuesto de mundo abierto".
Esto significa que las instancias de typeclass también se exportan de forma transitoria: si importa una biblioteca con una instancia, también se exporta desde su módulo.
En este caso, la instancia de IsString
está en Data.ByteString.Char8
, que es importada por Data.ByteString.Base16
. Debería poder reemplazar su importación con:
import Data.ByteString.Char8 ()
Hay una buena pregunta de SO que proporciona información sobre el supuesto de mundo abierto, si está interesado.