小编bga*_*ari的帖子

在Repa数组上的并行mapM

在我最近的工作Gibbs sampling,我一直在充分利用RVar它,在我看来,它为随机数生成提供了一个近乎理想的界面.遗憾的是,由于无法在地图中使用monadic动作,我无法使用Repa.

虽然一般来说明显的monadic地图不能并行化,但在我看来,这RVar可能至少是monad的一个例子,其中效果可以安全地并行化(至少在原则上;我对内部工作原理并不十分熟悉RVar) .也就是说,我想写下面的内容,

drawClass :: Sample -> RVar Class
drawClass = ...

drawClasses :: Array U DIM1 Sample -> RVar (Array U DIM1 Class)
drawClasses samples = A.mapM drawClass samples
Run Code Online (Sandbox Code Playgroud)

这里A.mapM看起来是这样的,

mapM :: ParallelMonad m => (a -> m b) -> Array r sh a -> m (Array r sh b)
Run Code Online (Sandbox Code Playgroud)

虽然这显然是如何工作的,但关键取决于其实现RVar及其基础RandomSource,原则上人们会认为这将涉及为每个产生的线程绘制一个新的随机种子并照常进行.

直觉上,似乎同样的想法可能会推广到其他一些monad.

所以,我的问题是:是否可以构建一个ParallelMonadmonad 类,其效果可以安全地并行化(可能至少有人居住RVar)?

它看起来像什么?还有哪些monad可能会在这个课程中出现?还有其他人考虑过如何在维修中使用它的可能性吗?

最后,如果并行monadic动作的这个概念不能概括,那么有没有人看到任何好的方法来使这个工作在特定的情况下RVar(它将非常有用)?放弃 …

arrays parallel-processing haskell repa

87
推荐指数
2
解决办法
2209
查看次数

在不使用断点的情况下在GHCi调试器中中断并继续

在传统的命令式调试器中,例如gdb可以使用,进入程序执行SIGINT,检查程序状态,最终恢复执行.

虽然GHCi允许在任意点闯入程序执行-fbreak-on-exception,但尝试恢复执行:continue只会导致解释器继续使用异常处理程序并终止程序,

> let main = findCureForCancer
> :set -fbreak-on-exception
> :trace main
[twiddle thumbs]
[why is this taking so long?]
[maybe something is wrong, I better see what it's doing]
^CStopped at <exception thrown>
_exception :: e = GHC.Exception.SomeException
                    GHC.IO.Exception.UserInterrupt
> :hist
...
[ahh, looks like this will just take a bit longer]
> :continue
[program should keep running]
Run Code Online (Sandbox Code Playgroud)

在使用GHCi调试器进行一些调整后,是否有可能进入执行并仍然恢复执行?

debugging haskell ghc ghci

20
推荐指数
1
解决办法
891
查看次数

为什么没有`-XDeriveApplicative`扩展?

GHC具有几个有用的语言的扩展,用于机械地导出各种常见的Haskell类型类(-XDeriveFunctor,-XDeriveFoldable,-XDeriveTraversable).似乎这Applicative是另一个经常需要并经常容易衍生出来的课程.对于包含类型插槽的简单记录a,例如,

data SimpleRecord a = Simple a a a
Run Code Online (Sandbox Code Playgroud)

Applicative实例是非常简单的,

instance Applicative SimpleRecord where
    pure x = Simple x x x
    Simple a1 b1 c1 <*> Simple a2 b2 c2 = Simple (a1 a2) (b1 b2) (c1 c2)
Run Code Online (Sandbox Code Playgroud)

即使在稍微更难的情况下,某些a值被埋在其他应用程序中,例如,

data MyRecord f a = MyRecord (f a) a
Run Code Online (Sandbox Code Playgroud)

一个合理的实例很容易写,

instance (Applicative f) => Applicative (MyRecord f) where
    pure x = MyRecord (pure x) x …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

16
推荐指数
2
解决办法
556
查看次数

具有下游状态且没有损失的惯用双向管道

假设我有简单的生产者/消费者模型,消费者想要将一些状态传递给生产者.例如,让下游流动的对象成为我们想要写入文件的对象,上游对象是表示在文件中写入对象的位置的一些标记(例如,偏移).

这两个过程可能看起来像这样(带pipes-4.0),

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Pipes
import Pipes.Core
import Control.Monad.Trans.State       
import Control.Monad

newtype Object = Obj Int
               deriving (Show)

newtype ObjectId = ObjId Int
                 deriving (Show, Num)

writeObjects :: Proxy ObjectId Object () X IO r
writeObjects = evalStateT (forever go) (ObjId 0)
  where go = do i <- get
                obj <- lift $ request i
                lift $ lift $ putStrLn $ "Wrote "++show obj
                modify (+1)

produceObjects :: [Object] -> Proxy X () ObjectId Object …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-pipes

14
推荐指数
1
解决办法
1009
查看次数

堆栈溢出在大型列表中的幺半折叠

先是一些imports,

import Control.Applicative
import Data.Traversable as T
import Data.Foldable as F
import Data.Monoid
Run Code Online (Sandbox Code Playgroud)

假设我有一个拿着一对值的仿函数,

data Fret a = Fret a a deriving (Show)

instance Functor Fret where fmap f (Fret a b) = Fret (f a) (f b)

instance Applicative Fret where
    pure a = Fret a a
    Fret aa ab <*> Fret ba bb = Fret (aa ba) (ab bb)

instance Monoid a => Monoid (Fret a) where
    mempty = Fret mempty mempty
    a `mappend` b = …
Run Code Online (Sandbox Code Playgroud)

stack-overflow haskell monoids

5
推荐指数
1
解决办法
288
查看次数

用管道的WriterP编写一个简单的累加器

使用管道库,我想编写一个程序来从某个源读取数据并单独累积它(比如说Sum).最简单的方法是,

 import Control.Proxy as 
 import Data.Monoid (Sum)

 main = do
     let source = enumFromToS (0::Int) 5
     a <- runWriterT $ runProxy $ source >-> foldD Sum
     print a
Run Code Online (Sandbox Code Playgroud)

当然,虽然这适用于小型源,但由于WriterT累加器的惰性,大输入会导致可怕的堆栈溢出.

值得庆幸的是,它似乎pipes预料到了这一点,提供了一个WriterP带有严格累加器的代理.不幸的是,围绕这个代理的文档非常稀少.经过一番探索(并简化问题而不是为每个下游元素累积1),我来到这个程序,

import Control.Proxy
import Control.Proxy.Trans.Writer
import Data.Monoid (Sum)

main = do
    let source = enumFromToS (0::Int) 5
    a <- runProxy $ runWriterK $ source >-> \x->tell (Sum 1::Sum Int)
    print a
Run Code Online (Sandbox Code Playgroud)

当然,这个程序甚至没有正确地执行简化的任务,因为它累积到1而不是6.如果我没有弄错,这个行为可以解释为管道在终止之前只读取一个元素.要重复直到输入结束,我想出了以下内容,

import Control.Proxy
import Control.Proxy.Trans.Writer
import Data.Monoid (Sum)

main = do
    let …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-pipes

4
推荐指数
1
解决办法
537
查看次数

Haskeline:为`ReaderT r(StateT sm)`堆栈实现`MonadException`实例

假设我有以下monad变换器堆栈(r并且为了简单起见而s留下()),

newtype MyMonad m a = MM (ReaderT () (StateT () m a)
Run Code Online (Sandbox Code Playgroud)

如果我想将它用作haskeline的基础monad InputT,我需要一个System.Console.Haskeline.MonadException实例.鉴于这些实例的明显复杂性,我宁愿让编译器为我推导出这个GeneralizedNewtypeDeriving.具体来说,我希望以下内容可以进行类型检查,

{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving, FlexibleContexts #-}

import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.IO.Class
import Control.Applicative
import System.Console.Haskeline.MonadException

newtype MyMonad m a = MM (ReaderT () (StateT () m) a)
                    deriving (Functor, Applicative, Monad, MonadIO)
deriving instance (MonadException m) => MonadException (MyMonad m)        
Run Code Online (Sandbox Code Playgroud)

可悲的是,这给了我,

/home/bgamari/hi.hs:11:1:
    Could not deduce (MonadException (StateT () m))
      arising from …
Run Code Online (Sandbox Code Playgroud)

haskell

1
推荐指数
1
解决办法
235
查看次数