gpt4 book ai didi

Haskell 如何在 haskell 中强制评估 Data.Map?

转载 作者:行者123 更新时间:2023-12-02 00:05:39 28 4
gpt4 key购买 nike

所以我有一张严格的 map

import qualified Data.Map.Strict      as Map
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as C

type Key = Int
type Value = BS.ByteString

data KeyValue = KeyValue !(Map.Map Key Value)

source :: [(Key, Value)]
source = zip [0..] $ map (\x -> BS.concat $ replicate 10000 $ "alsfdd" `C.append` (C.pack $ show x)) [0..10000]
每次我放置一个元素时,我都试图让 Map 进行评估......
 putStrLn "Putting 10000 Strict ByteStrings into a Map"
let newMap = foldr (\(k,v) i -> Map.insert k v $! i) Map.empty source
putStrLn "Done..."
putStrLn "Launching interactive mode"
forever $ do
putStrLn "Enter an integer:"
k <- getLine
print $ Map.lookup (read k) newMap
但是,在我进入“交互模式”并提交查询之前, map 不会进行评估。
我可以对其进行评估的唯一方法是打印其大小:
newMap <- foldM (\i (k, v) -> (print $ Map.size i) >> (return Map.insert k v i)) Map.empty source
我如何使用 seq$!正确吗?
关于我的实际问题的更多详细信息,这是基于:
我应该注意到,在我的原始程序中,Map 包含在 TVar 中,元素被插入到 IO 事件中。所以对我来说,为什么如果我修改 TVar haskell 不强制对 Map 进行评估是没有意义的。我的程序是一个多线程套接字服务器,其中一个地址是执行查找的“读取器”。另一个套接字地址只是将字节串推送到映射上。我可以将 2 个 socket 连接到插入件,将 1 个 socket 连接到阅读器。如果我多次插入,则在我的阅读器套接字查找值之前不会评估 map 。我希望在修改 TVar 时评估 map 。我发现这样做的唯一方法是在我修改插入件上的 TVar 之前打印 map 的大小。
编辑:
所以我尝试了一种 bang 模式,它适用于上面的示例,但不适用于我的服务器:
buildIndex :: Int -> ByteString -> M.Map Int ByteString -> M.Map Int ByteString

liftIO $ do indexed <- readTVarIO tvi
let !newIndex = buildIndex nextKey serialized indexed
atomically $ writeTVar tvi $! newIndex

最佳答案

我建议使用 bang 模式,因为它通常是强制评估某些内容的最简单方法。问题是,当您使用 Map 的严格版本时和 ByteString ,并非您执行的每个操作都是严格的,因此不会立即计算源。不要试图追踪每个被懒惰评估的语句,只需添加 {-# LANGUAGE BangPatterns #-}到文件顶部并更改 let newMap = ...let !newMap = ... .就是这样。

有一些技术可以手动追踪和消除懒惰,但爆炸模式是迄今为止我见过的最简单和最快的技术。

关于Haskell 如何在 haskell 中强制评估 Data.Map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18523006/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com