例如,我无法将其标记为包含"安全"的代码
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")]
Run Code Online (Sandbox Code Playgroud)
因为(显然)Data.String.Utils
不是"安全的".
有安全的选择replace
吗?为什么replace
不安全呢?
tl;dr:import Data.Text (replace)
- 您是否可以接受更受限制的类型签名?
1) 该Data.String.Utils
模块没有被标记为安全,尽管它应该是。
2)Data.String.Utils
模块安全。称其为“不安全”是错误的,即使您在“安全”周围加了引号。GHC 告诉您该模块将是不安全的,因为它使用保守的方法:如果它无法在编译时证明该模块是安全的,它就会假设它是不安全的。但无论编译器多么大声地抱怨该模块不安全,它仍然是完全安全的。
3) 另一方面,可以编写一个模块,导出某个版本的unsafePerformIO
,并将其标记为“值得信赖”。GHC 会认为该模块可以安全地导入。但事实上,该模块本质上是不安全的。
那么,你现在有什么选择呢?
A) 下载软件包的源代码,并修改您需要的并且您知道它们是安全的模块,以在开头包含“Trustworthy”标签:{-# LANGUAGE Trustworthy #-}
(您可以将补丁发送给维护者,也可以自己保留)
B) 您编写自己的版本replace
并将其标记为安全。
C) 也许你可以使用replace
from Data.Text
。但这仅限于Text
,而另一个replace
函数适用于任意列表。
至少在Hoogle上没有其他方法具有[a] -> [a] -> [a] -> [a]
适合您的用例的签名。