Haskell—希望从不包含';不变 type Anagrams=映射字符串[String] 构建语法::IO语法 buildAnagrams=do 列出字谜->字谜 fs=Map.insertWith(++)(排序s)[s]
我有这个函数,它可以构建一个映射,从一个不变的字典文件中查找字谜。我想把map作为一个全局变量,因为它需要被其他函数使用。目前,函数正在buildAnagrams上使用unsafePerformIO,但我知道这是不推荐的。整个程序也非常缓慢,因为它多次构建地图。必须有更好的方法才能做到这一点?如果您想将字谜数据保存在外部文件中,则需要IO来读取它。因此,您有几个选择:Haskell—希望从不包含';不变 type Anagrams=映射字符串[String] 构建语法::IO语法 buildAnagrams=do 列出字谜->字谜 fs=Map.insertWith(++)(排序s)[s],haskell,unsafe-perform-io,Haskell,Unsafe Perform Io,我有这个函数,它可以构建一个映射,从一个不变的字典文件中查找字谜。我想把map作为一个全局变量,因为它需要被其他函数使用。目前,函数正在buildAnagrams上使用unsafePerformIO,但我知道这是不推荐的。整个程序也非常缓慢,因为它多次构建地图。必须有更好的方法才能做到这一点?如果您想将字谜数据保存在外部文件中,则需要IO来读取它。因此,您有几个选择: 将字谜数据作为额外参数传递给所有函数 使用 将所有内容包装在单子中(或添加一个转换器) 使用unsafePerformIO,使
- 将字谜数据作为额外参数传递给所有函数
- 使用
- 将所有内容包装在单子中(或添加一个转换器)
- 使用
,使用unsafePerformIO
unsafePerformIO
:如果您绝对确定您读取的文件不会更改,这是它的“安全”用例之一。虽然不是真正推荐的,也不是很优雅,但它可以解决这个问题。为避免多次重新读取数据,应使用
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]
这样外部文件将只读取一次
另一种选择是在Haskell源代码中包含外部文件。这可以通过几种方式实现,包括
- 普通元编程:编写一个程序,将外部文件转换为.hs文件,该文件声明一个大字符串向量
- :与元编程效果相同,但更优雅一点
unsafePerformIO
。其次,Haskell中没有变量。有xVar
s和IORef
s和State
;选择取决于您的需要和程序体系结构。您可能希望编写以Anagrams
为参数的函数,并使其在main
中的任何位置都可用(这将执行IO
效果)。读者monad会系统地捕捉到这个想法(并注意将参数提供给所有函数)。谢谢。这些都是很好的选择。我尝试过unsafePerformIO one作为一个快速修复程序,而且速度快得多。在模板Haskell方面,实现这一点的一个简单方法是使用该软件包。@chi我在全局配置方面也有类似的问题。你能解释一下或指出一些关于ReaderT解决方案的有用资源吗?@mb14我找不到任何具体的资源,但是有一些关于monad transformers的教程也涉及ReaderT,例如,这就是我要找的。
{-# NOINLINE allAnagrams #-}
allAnagrams :: Anagrams
allAnagrams = unsafePermformIO buildAnagrams