我无法将"Safe"代码标记为包含,例如
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")]
因为(显然)Data.String.Utils
&#34; s不安全&#34;。
是否有replace
的安全替代方案?那为什么replace
无论如何都不安全?
答案 0 :(得分:1)
tl; dr:import Data.Text (replace)
- 如果你可以使用更受限制的类型签名?
1)Data.String.Utils
模块未标记为 safe ,尽管它应该是。
2)Data.String.Utils
模块 是安全的。把它称为“不安全”是错误的,即使你把报价放在&#34;安全&#34;。 GHC告诉你模块是不安全的,因为它使用了一种保守的方法:如果它不能在编译时证明模块是安全的,那么它就假定它是不安全的。但无论编译器多么大声抱怨模块不安全,它仍然是完全安全的。
3)另一方面,可以编写一个模块,导出某个版本的unsafePerformIO
,并将其标记为&#34; Trustworthy&#34;。 GHC会认为该模块可以安全导入。但实际上,该模块本质上是不安全的。
那么,您现在有什么选择?
A)下载软件包的源代码,并修改您需要的软件,并且知道它们是安全的,包括一个&#34;可信赖的&#34;开头标记:{-# LANGUAGE Trustworthy #-}
(您可以向维护者发送补丁,或者您可以将其保留给自己)
B)您编写自己的replace
版本并将其标记为安全。
C)也许您可以使用replace
中的Data.Text
。但这仅限于Text
,而另一个replace
函数适用于任意列表。
至少在Hoogle上,没有其他方法可以为您的用例提供[a] -> [a] -> [a] -> [a]
签名。