因此,在用一些Haskell压缩了最后一点性能后,我正在使用将推文数据分解为n-gram,我遇到了空间泄漏问题.当我进行分析时,GC使用大约60-70%的过程,并且有大量内存部分专用于拖动.希望一些Haskell大师能够在我出错的时候提出建议.
{-# LANGUAGE OverloadedStrings, BangPatterns #-}
import Data.Maybe
import qualified Data.ByteString.Char8 as B
import qualified Data.HashMap.Strict as H
import Text.Regex.Posix
import Data.List
import qualified Data.Char as C
isClassChar a = C.isAlphaNum a || a == ' ' || a == '\'' ||
a == '-' || a == '#' || a == '@' || a == '%'
cullWord :: B.ByteString -> B.ByteString
cullWord w = B.map C.toLower $ B.filter isClassChar w
procTextN :: Int -> B.ByteString -> [([B.ByteString],Int)]
procTextN n …Run Code Online (Sandbox Code Playgroud) 所以我的问题如下.我正在尝试为RDB文件(Redis生成的转储文件)实现流式解析器.我想实现一个类似于mapM_的函数,我可以说,在解析时打印出转储文件中表示的每个对象.但是,我似乎无法让它在恒定的空间中运行.我发现正在发生的事情是我在Get monad中构建一个大的IO()thunk,从Get monad返回然后执行IO.无论如何流式传输我的对象,因为它们被分析打印然后丢弃它们?我尝试过Enumerators and Conduits,但我没有看到任何真正的收获.这是我到目前为止:
loadObjs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a)
loadObjs_ f = do
code <- lookAhead getWord8
case code of
0xfd -> do
skip 1
expire <- loadTime
getPairs_ f (Just expire)
0xfc -> do
skip 1
expire <- loadTimeMs
getPairs_ f (Just expire)
0xfe -> f Nothing "Switching Database" RDBNull
0xff -> f Nothing "" RDBNull
_ -> getPairs_ f Nothing
getPairs_ :: (Monad …Run Code Online (Sandbox Code Playgroud) 所以,我正在进行一个有趣的实验,在上下文意义上,我正在碰壁.我正在尝试定义一种数据类型,该数据类型可以是基元,也可以是从一个构造函数转换为另一个构造函数的函数.
data WeaponPart =
WInt Int |
WHash (Map.Map String Int) |
WNull |
WTrans (WeaponPart -> WeaponPart)
instance Show WeaponPart where
show (WInt x) = "WInt " ++ (show x)
show (WHash x) = "WHash " ++ (show x)
show (WTrans _) = "WTrans"
show WNull = "WNull"
cold :: WeaponPart -> WeaponPart
cold (WInt x) = WHash (Map.singleton "frost" x)
cold (WHash x) = WHash $ Map.insertWith (+) "frost" 5 x
cold (WTrans x) = cold $ x …Run Code Online (Sandbox Code Playgroud) 我一直在阅读 John Hughes 的 Programming with Arrows,我得到了第一个练习,他要求读者为箭头实现一个通用的过滤器函数 filterA。规范说它应该像过滤 (->) 箭头和 filterM 过滤 Kliesli 箭头一样。我尝试按如下方式实现它,但我最终得到的结果似乎比我在网上看到的其他解决方案示例要简单一些。我担心我错过了一些东西,但我的答案似乎符合规范的建议。它匹配 filter for -> 和 filterM for Kliesli 箭头。对于流函数,它也以合理的方式工作。
listcase [] = Left ()
listcase (x:xs) = Right (x,xs)
filterA :: forall a arr. ArrowChoice arr => arr a Bool -> arr [a] [a]
filterA f = arr listcase >>>
arr (const []) ||| (switchA *** filterA f >>> arr (uncurry (++)))
where switchA :: ArrowChoice arr => arr a [a]
switchA = (f &&& id) >>> …Run Code Online (Sandbox Code Playgroud) 刚刚开始编写Go代码,我遇到了一个有趣的问题.
有没有办法轻松迭代数组中的项目,这些项目作为空接口引入而没有代码重复?考虑以下:
function(someArr interface{}){
switch someArr.(type){
case []int :
arr := (someArr).([]int)
for i := range (arr) {
// CODE
}
case []string :
arr := (someArr).([]string)
for i := range (arr) {
// CODE
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,CODE中的代码完全相同.但是,我无法将其从交换机中取出,因为类型断言arr将超出范围.同样,我无法在切换之前定义arr,因为我不知道它将是什么类型.这可能无法完成.在那种情况下,当我用一个不规则的模式(某些数组的int,某些数组或字符串)解析JSON时,对于这种事情有什么更好的习惯用法?