type Anagrams = Map String [String]
buildAnagrams :: IO Anagrams
buildAnagrams = do
list <- readCSV "mydict.csv"
return $ foldr f Map.empty list
where
f :: String -> Anagrams -> Anagrams
f s = Map.insertWith (++) (sort s) [s]
我有这个函数构建一个映射来从字典文件中查找anagrams,该文件不会改变。我希望将地图作为全局变量,因为它需要被其他函数使用。目前函数在buildAnagrams上使用unsafePerformIO,但我知道不建议这样做。整个程序也很慢,因为它多次构建地图。必须有更好的方法来做到这一点吗?
答案 0 :(得分:5)
如果要将anagram数据保存在外部文件中,则需要IO才能读取它。所以,你有几个选择:
Reader
monad中(或添加ReaderT
变换器)unsafePerformIO
unsafePerformIO
关于{-# NOINLINE allAnagrams #-}
allAnagrams :: Anagrams
allAnagrams = unsafePermformIO buildAnagrams
:如果您完全确定您阅读的文件不会改变,那么这是其“安全”用例之一。虽然不是真的推荐或优雅,但它可以解决这个问题。为避免多次重读数据,您应该使用
{{1}}
以便外部文件只读取一次。
另一种选择是将您的外部文件包含在Haskell源中。这可以通过几种方式完成,包括