2
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]

我有这个函数可以构建一个映射来从一个不变的字典文件中查找字谜。我想将地图作为全局变量,因为它需要被其他函数使用。目前,这些函数在 buildAnagrams 上使用 unsafePerformIO,但我知道不建议这样做。整个程序也很慢,因为它要多次构建地图。必须有更好的方法来做到这一点?

4

1 回答 1

5

如果要将字谜数据保存在外部文件中,则需要 IO 来读取它。所以,你有几个选择:

About unsafePerformIO:如果您绝对确定您阅读的文件不会更改,这是它的“安全”用例之一。虽然不是真的推荐或优雅,但它可以解决这个问题。为避免多次重新读取数据,您应该使用

{-# NOINLINE allAnagrams #-}
allAnagrams :: Anagrams
allAnagrams = unsafePermformIO buildAnagrams

这样外部文件将只被读取一次。

另一种选择是将您的外部文件包含在您的 Haskell 源中。这可以通过几种方式完成,包括

  • 普通元编程:您编写一个程序,该程序获取您的外部文件并将其转换为 .hs 文件,该文件声明一个大字符串向量
  • 模板 Haskell:与元编程相同的效果,但更优雅一点
于 2014-12-08T11:50:53.800 回答