I'm unable to mark as "Safe" code containing, for example
import Data.String.Utils (replace)
preproc :: String -> String
preproc s = foldl1 fmap (uncurry replace <$> subs) s
where subs = [("1","a"),("2","bb"),("3","z"),("4","mr")("0","xx")]
because (apparently) Data.String.Utils
's is not "safe".
Is there a safe alternative to replace
? And why isn't replace
safe anyway?
tl;dr: import Data.Text (replace)
- if you can live with the more restricted type signature?
1) The Data.String.Utils
module is not tagged as safe, although it should be.
2) The Data.String.Utils
module is safe. Its wrong to call it "not safe", even if you put quotes around "safe". GHC tells you that the module would be unsafe, because it uses a conservative approach: if it can't prove at compile time that the module is safe, it assumes that it is unsafe. But no matter how loud the compiler complains that the module would be unsafe, it still remains perfectly safe.
3) On the other hand, it would be possible to write a module, export some version of unsafePerformIO
, and mark it as "Trustworthy". GHC would think that the module can be safely imported. But in fact, the module is inherently unsafe.
So, what are your options now?
A) Download the source of the package, and modify the modules that you need, and for which you know that they are safe, to include a "Trustworthy" tag at the beginning: {-# LANGUAGE Trustworthy #-}
(You may send a patch to the maintainer, or you may keep it to yourself)
B) You write your own version of replace
and mark it as safe.
C) Maybe you can use replace
from Data.Text
. But that is limited to Text
, whereas the other replace
function works on arbitrary lists.
At least on Hoogle there are no other methods with a [a] -> [a] -> [a] -> [a]
signature for your use-case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With