- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想学习使用 ST-Monad。因此,我想为每个整数重写一些代码计算——直到一个极限——所有它的真因数的列表。结果应该是一个数组,索引“n”的条目应该是它的真除数的列表。
这是通过为每个整数“n”计算其倍数的列表“l”,并将“l”中的每个倍数“m”添加到索引“m”处的除数“n”到列表中来完成的。
这是我要修改的代码:
properDivisorsOf' :: forall a. (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf' limit =
let generate :: (Integral a, Ix a) => a -> Array a [a] -> Array a [a]
generate n acc
| n > (limit `div` 2) = acc
| otherwise =
let acc' = acc // [(i, n : (acc ! i)) | i <- [2*n, 3*n .. limit]]
in generate (n + 1) acc'
in generate 1 (array (1, limit) [(i, [])| i <- [1..limit]])
这就是我尝试的方式:
properDivisorsOf :: forall a. (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf limit =
let result :: ST s (STArray s a [a])
result = newArray (1, limit) [] -- In the beginning for every number: no divisors known (empty list)
update (index, divisor) = do
l <- readArray result index -- extracting list of divisors of number 'index'
let u = divisor : l
writeArray result index u -- and adding 'divisor' to the list
content :: [(a, a)]
content = do
n <- [1 .. (limit `div` 2)]
multiple <- [2*n, 3*n .. limit]
return (multiple, n)
doUpdate = map update content -- update result for all multiples (in content)
在 runSTArray 结果中
不幸的是,它没有编译,并且错误消息没有对我说什么。我有两个问题:
编辑:编译器消息
Couldn't match expected type `[t0]'
with actual type `STArray i0 a [a]'
In the second argument of `(:)', namely `l'
In the expression: divisor : l
In an equation for `u': u = divisor : l
失败,已加载模块:无。
最佳答案
2. How would an experienced Haskell-Programm solve this problem under the restriction that he has to work with the ST-Monad (for efficiency purposes)?
我绝不是一个经验丰富的 Haskell 程序员,但我会使用
以下代码
下面的命令式代码,但这是从您的代码直接转换:
properDivisorsOf :: forall a. (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf limit =
runSTArray $ do
result <- newArray (1, limit) []
mapM_ (update result) content
return result
where
content :: [(a, a)]
content = do
n <- [1 .. (limit `div` 2)]
multiple <- [2*n, 3*n .. limit]
return (multiple, n)
update arr (index, divisor) = do
l <- readArray arr index -- extracting list of divisors of number 'index'
let u = divisor : l
writeArray arr index u -- and adding 'divisor' to the list
你原来的功能:
main = print $ properDivisorsOf' 100000
$ .\Original.exe +RTS -sOriginal.exe: out of memory
We exchange 100000
by 10000
:
221,476,488 bytes allocated in the heap 21,566,328 bytes copied during GC 172,813,068 bytes maximum residency (9 sample(s)) 4,434,480 bytes maximum slop 210 MB total memory in use (5 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 378 colls, 0 par 0.41s 0.43s 0.0011s 0.0024s Gen 1 9 colls, 0 par 0.36s 0.37s 0.0409s 0.1723s INIT time 0.00s ( 0.00s elapsed) MUT time 0.28s ( 0.60s elapsed) GC time 0.77s ( 0.80s elapsed) EXIT time 0.00s ( 0.02s elapsed) Total time 1.05s ( 1.42s elapsed) %GC time 73.1% (56.4% elapsed) Alloc rate 787,471,957 bytes per MUT second Productivity 26.9% of total user, 19.8% of total elapsed
Even though the program is pretty fast (1s after all), the memory footprint of 210MB is quite noticeable. Also, the memory needed grows squre, for a limit of 20000 you would need around 800 MB, for 20000 around 1.9GB.
$ .\ST.exe +RTS -s > $null 300,728,400 bytes allocated in the heap 89,696,288 bytes copied during GC 13,628,272 bytes maximum residency (10 sample(s)) 292,972 bytes maximum slop 38 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 565 colls, 0 par 0.14s 0.14s 0.0002s 0.0008s Gen 1 10 colls, 0 par 0.09s 0.08s 0.0076s 0.0223s INIT time 0.00s ( 0.00s elapsed) MUT time 0.11s ( 0.16s elapsed) GC time 0.23s ( 0.21s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 0.34s ( 0.38s elapsed) %GC time 68.2% (56.6% elapsed) Alloc rate 2,749,516,800 bytes per MUT second Productivity 31.8% of total user, 28.9% of total elapsed
Only 38 MB, which is ~17% of your original implementation, but calculates 10 times more values (10000 vs 100000).
If you throw content
away, you'll end up with the following program:
import Data.Array (Array(..), Ix)
import Data.Array.ST (newArray, readArray, writeArray, runSTArray)
import Control.Monad (forM_)
properDivisorsOf :: (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf limit =
runSTArray $ do
result <- newArray (1, limit) []
forM_ [1.. (limit `div`2)] $ \n -> do
forM_ [2*n, 3*n .. limit] $ \index -> do
l <- readArray result index
writeArray result index (n:l)
return result
main = print $ properDivisorsOf 100000
$ .\Imperative.exe +RTS -s > $null 237,323,392 bytes allocated in the heap 63,304,856 bytes copied during GC 13,628,276 bytes maximum residency (7 sample(s)) 138,636 bytes maximum slop 34 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 447 colls, 0 par 0.12s 0.09s 0.0002s 0.0008s Gen 1 7 colls, 0 par 0.05s 0.06s 0.0087s 0.0224s INIT time 0.00s ( 0.00s elapsed) MUT time 0.11s ( 0.18s elapsed) GC time 0.17s ( 0.16s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 0.30s ( 0.34s elapsed) %GC time 57.9% (45.9% elapsed) Alloc rate 2,169,813,869 bytes per MUT second Productivity 42.1% of total user, 36.9% of total elapsed
- Why doesn't it compile? How can I extract the entry correctly?
我感觉,您提取正确(见上文,这与您使用的代码几乎相同),但是 update
的推断类型是错误的,因为您的用法不正确。例如,update
应该在 ST
monad 中工作,因此您可以将其与 mapM
一起使用,而不是与 map
一起使用。此外,还有一些其他问题,例如您定义了 doUpdate
但从未使用它。
关于haskell - ST-Monad 中的多项更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21779762/
monad 被定义为类别 C 上的内仿函数。假设 C 具有类型 int 和 bool 以及其他构造类型作为对象。现在让我们考虑在这个类别上定义的列表 monad。 根据它的定义,list 是一个内仿函
我试图采取例如ExceptT a (StateT A M) , 对于某些具体类型 A和单子(monad)M ,并将它们包装到我的新自定义单子(monad)中。 首先我确定StateT A M经常出现在
我读到(例如 here 和 here )所有基本单子(monad)(Mabye, Error, ...) 源自其相应的 monad 转换器(MaybeT, ErrorT, ...) 使用身份 mona
Haskell 的状态单子(monad) State s a迫使我保持相同类型的 s在整个做 block 期间。但是由于 state monad 实际上只是一个函数,如果我将它定义为 State
我一直在阅读some materials on free monads而且我真的不认为我离实现更近了,但我认为我更接近于理解它们是什么! 鉴于上述大量资源,我的理解是自由单子(monad)从“计算”工
假设我有一个由两个 monad 操作组成的函数: co::Monad m => m a -> m a -> m a 您可以将 co 视为一个高阶函数,它描述两个单子(monad)操作如何相互协作来完成
在 SO解释了为什么像 scalaz、cats (Scala) 或 Arrow (Kotlin) 中的 Validation 不能是 monad。 据我所知,这是因为他们已经根据应用仿函数对 mona
我对 Haskell 还很陌生,并且慢慢地意识到 Monad fail 的存在有问题。真实世界的 Haskell warns against its use (“再一次,我们建议您几乎总是避免使用失败
我正在阅读现实世界 Haskell 中的 monad 转换器。在以下示例中,堆栈为 Writer在顶部State在Reader之上在IO之上。 {-# Language GeneralizedNewt
我看到的典型 Pause monad 实现如下所示(基于 Giulia Costantini 和 Giuseppe Maggiore 编写的 Friendly F# 的第 5 章)。 open Sys
“Monads 允许程序员使用顺序构建 block 来构建计算”,因此它允许我们组合一些计算。如果是这样,那为什么下面的代码不能运行呢? import Control.Monad.Trans.Stat
这是我第一次认识 Monad Transformers,所以答案可能很明显。 假设我在 StateT MyMonad MyType 类型的 do 块中,我想让另一个相同类型的函数修改状态并返回 MyM
人们通常说类型是单子(monad)。 在某些函数式语言和库(如 Scala/Scalaz)中,您有一个类型构造函数,如 List 或 Option,您可以定义一个与原始类型分离的 Monad 实现。所
我的目标是创建一个函数,该函数在 ReaderT WriterT 堆栈或 RWS 堆栈中使用 list monad。更一般地说,我如何在 mtl 类型类(如 MonadReader、MonadWrit
我只是想知道是否有一个简洁的术语来表示既是单子(monad)又是单子(monad)的东西。我做了一些搜索,我知道these structures exist ,但我还没有找到他们的名字。 最佳答案 在
我正在玩写一个网络应用程序。在这种情况下,我使用 scotty和 redis ,但是这个问题出现在任何 web/db 组合中。在此之前我使用了 happstack,所以我也喜欢那里的一个例子。 Sco
是 x >>= f相当于 retract (liftF x >>= liftF . f) ? 也就是说,从同样是 Monad 的 Functor 构建的自由 monad 的 monad 实例是否将具有
我正在尝试编写一个只能包含 Num 的新 monad。当它失败时,它返回 0,就像 Maybe monad 在失败时返回 Nothing 一样。 这是我到目前为止所拥有的: data (Num a)
我正在使用 operational monad作者:海因里希·阿普菲尔姆斯。 我想用结果类型的 monad 参数化解释器。 我的代码的以下版本编译: {-# LANGUAGE GADTs #-} im
假设所有的 monad 都可以用 Free 来表示。 (如果这不是真的,什么是反例,为什么)?怎么可能the continuation monad或其对应的变压器用 Free 表示或 FreeT -
我是一名优秀的程序员,十分优秀!