[Haskell-cafe] Safe Haskell?

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Sat Apr 17 16:08:44 UTC 2021


Dear Richard,

> Thanks for speaking up here. I feel like I'm missing something I
> should know, but how does Safe help you? Looking at the lambdabot
> docs, users cannot import their own modules, and you describe the
> libraries as curated. So, presumably, that's enough to keep
> unsafeCoerce and unsafePerformIO from being in scope. Along similar
> lines, I don't see a way in lambdabot to enable extensions, so
> Template Haskell is not an issue for you (I believe).

Lambdabot maintains a Haskell source file (the pristine version can be
seen here, for example):

  https://silicon.int-e.eu/lambdabot/State/Pristine.hs

There's an @let command that can add to that source file, and while
the name suggests that it is for adding definitions, it can also add
imports. So one can try

  @let import System.IO.Unsafe

which is currently blocked by SafeHaskell:

  <lambdabot> .L.hs:140:1: error:
  <lambdabot> System.IO.Unsafe: Can't be safely imported!

The use of @let for importing modulues probably not documented
anywhere, but it is occasionally demonstrated on the #haskell IRC
channel.

You're right about Template Haskell though. @let doesn't allow adding
new language pragmas.

> Maybe the role of Safe is in helping you curate your libraries? That
> is, you can use the Safety of a module in determining whether or not
> it should be imported. That is indeed helpful. Is that it, though?
> Does enabling -XSafe when compiling user-supplied code catch some
> scenarios that would be uncaught otherwise?

There are two ways in which Safe Haskell helps with curation. First,
the import restriction that helps @let also helps with adding new
permanent imports to Pristine.hs in pretty much the same way; a module
that can be safely imported should not break the type system or allow
"pure" functions that do arbitrary IO.

But Safe Haskell also helps on a package level, since we have two
tiers of trust:

- for untrusted packages, modules are only regarded as safe if their
  safety is inferred, and the inference mechanism is strong enough to
  propagate the two safety criteria lambdabot cares about (type
  safety, and lack of arbitrary IO ala unsafePerformIO). So just
  installing a package without trusting it requires little review (one
  can still worry about all the things a package can do during
  installation, through configure, Setup.hs or Template Haskell...)
  For trivial packages this can be good enough. (Sometimes it isn't
  for stupid reasons like IsList only being available through the
  Unsafe GHC.Exts module.)

- for trusted packages, at least one can focus ones attention to
  modules marked Trustworthy. How much this helps depends very
  much on the package; all imports of a Trustworthy package may
  have to be reviewed as well.

Because of this, the real curation happens at the level of packages to
be trusted; adding an untrusted package requires far less attention.

Cheers,

Bertram


More information about the Haskell-Cafe mailing list