在Clojure中,当处理的每个作业完全隔离并且可能生成需要评估的其他作业列表时,进行并行处理的正确方法是什么?
我的实际问题是一个营养计算问题,但我会把它放在象棋的形式,它与我的计算共享相同的问题空间特征.
例如,假设我试图在国际象棋游戏中找到Checkmate的所有动作.在搜索电路板状态时,我会从20个可能的状态开始,每个状态代表不同的可能开启动作.每个都需要进行评估,接受或拒绝,然后对于每个接受的移动,将创建一个新的工作列表,代表所有可能的下一步行动.这些工作看起来像这样:
initial: '([] proposed-move)
accepted: '([move] proposed-response)
'([move move] proposed-response)
Run Code Online (Sandbox Code Playgroud)
作为每次计算的结果,要评估的状态的数量增加,并且可以完全隔离所有其他状态来评估每个状态.
我正在玩的解决方案如下:
; a list of all final solutions, each of which is a sequence of moves
(def solutions (agent []))
; a list of all jobs pending evaluation
(def jobs (agent []))
Run Code Online (Sandbox Code Playgroud)
鉴于这些定义,我将拥有一个java线程池,每个线程都会从作业代理请求一个作业(并等待该请求得到满足).然后它将运行计算,生成解决方案列表和可能的解决方案.最后,它会将解决方案发送给解决方案代理,以及作业代理的可能解决方案.
在这种情况下,使用代理和线程的组合是最惯用的方式吗?我可以按照我提议的方式从作业队列中获取数据吗?
或者我的工作应该是java.util.concurrent.LinkedBlockingQueue,如具有资格的Producer consumer中所述?
我试图遵循Combine状态中给出的建议和IO动作来构建AppState以及IO monad.我得到的是这个:
module Main where
import Control.Monad.State
import Control.Monad.Trans
data ST = ST [Integer] deriving (Show)
type AppState = StateT ST IO
new = ST []
append :: Integer -> State ST ()
append v = state $ \(ST lst) -> ((), ST (lst ++ [v]))
sumST :: State ST Integer
sumST = state $ \(ST lst) -> (sum lst, ST lst)
script = do
append 5
append 10
append 15
sumST
myMain :: AppState () …Run Code Online (Sandbox Code Playgroud) 我有一个我正在研究的应用程序,我基本上是自学GUI编程.我在programmers.stackexchange上提出了一个相当复杂的问题.这个问题是关于我没有尝试过的想法的机制.
我有三个小部件:TreeView,TextField和DrawingArea.三个小部件中的每一个都与一个必然触发另一个动作的事件非常密切地交互.除了(到目前为止)读取包含全局应用程序状态的MVar 之外,这三个小部件在很大程度上不与应用程序的其余部分交互.
目前,我认为大型应用程序不应直接与这三个小部件中的任何一个进行交互.此外,将复制相同的模式以审查具有相同形式的其他数据.因此,在我看来,实际将这三个小部件绑定到一个更大的复合小部件中是有意义的,它可以与GTK的正常事件队列进行交互.所以,例如
type MyDataViewWidget = (TreeView, TextField, DrawingArea)
data DataUpdatedSignal a = DataUpdatedSignal a
data RedrawEvent a = RedrawEvent a
Run Code Online (Sandbox Code Playgroud)
因此,小部件将使用DataUpdatedEvent向应用程序的其余部分指示MyDataViewWidget内的某些内容发生了变化,而RedrawEvent会告诉小部件它需要重绘或重新读取源数据.
(从技术上讲,我没有在语义上考虑复合小部件中的各种操作会做什么...小部件是否只有应用程序数据的只读副本,需要使用RedrawEvent接收新的只读副本或也许这些小部件会拥有MVar本身并被允许更改MVar中的数据等...我只是对如何实际执行此操作感兴趣
做这样的事情有什么例子吗?基本上,我需要实现哪些实例来创建新的小部件和两个信号?我更喜欢坚持使用Haskell,但我可以使用C语言来构建新的小部件.
我正在使用blaze-html.我终于能够总结我的头脑如何使用它,但是一些monad和变换确实让我一直绊倒.但是这里有一个特殊的绊脚石(很多人都会这么做,但是我会离开这里再到Happstack的Response和ServerPart monad).
如果我想将字符串文本附加到段落,我必须使用此函数(来自Text.Blaze.Html5):
p . toHtml :: ToMessage a => a -> Html
Run Code Online (Sandbox Code Playgroud)
一切都很好,除了......
toHtml :: ToMarkup a => a -> Markup
p :: Html -> Html
Run Code Online (Sandbox Code Playgroud)
我尽我所能搜索文档,我看不出Markup monad和Html monad是如何相互关联的.我如何处理所有类型和类型类?
我正在使用本身使用zip-archive的hs-excelx库.zip-archive正在达到它调用的条件fail,在该特定上下文中,它会计算为对其的调用error.这是对error纯代码的调用.
我正在尝试检测特定文件是否实际上是Excel文件.实际上我必须在不崩溃的情况下检测到这一点,所以我编写了一个名为isExcel的函数来进行检测:
import qualified Data.Excelx as E
isExcel :: BS.ByteString -> Bool
isExcel = maybe False (\_ -> True) . E.toExcelx
Run Code Online (Sandbox Code Playgroud)
现在,问题在于这只是一种形式.如果你在一个不是zip存档的字节串上调用E.toExcelx,那么zip-archive就会error出来.
但是,我知道我正在调用isExcelIO代码,所以我编写了一个IO函数来尝试捕获这样的错误:
import qualified Data.ByteString.Lazy as BS
import Control.Exception
sd :: BS.ByteString -> IO Bool
sd bs = handle handler $ do
ie <- return $ Excel.isExcel bs
return (ie `seq` ie)
where
handler :: SomeException -> IO Bool
handler e = return False
> sd BS.empty
*** Exception: …Run Code Online (Sandbox Code Playgroud) 在我正在研究的Haskell应用程序中,我有一个API,我正在尝试设置一组可插拔的后端.我将有几种不同的后端类型,我希望调用者(现在,只是测试套件)来确定实际的后端.但是,我遇到了一个模糊的类型错误.
class HasJobQueue ctx queue where
hasJobQueue :: JobQueue queue => ctx -> queue
class JobQueue q where
enqueue :: MonadIO m => Command -> q -> m ()
type CloisterM ctx queue exc m = ( Monad m, MonadIO m, MonadError exc m, MonadReader ctx m
, AsCloisterExc exc
, HasJobQueue ctx queue
, JobQueue queue
)
createDocument :: forall ctx queue exc m. CloisterM ctx queue exc m => Path -> Document -> m DocumentAddr
createDocument path document …Run Code Online (Sandbox Code Playgroud) 与我最近关于处理大型数据块的问题密切相关,我已经达到了这样的程度,即我需要采用一个大的不可变数据块,使其对某些操作变得可变,然后在完成后再次使其变为不可变.
由于我想保留至少纯度的外观,可变数据将是原始不可变数据的可变副本.作为参考,我正在查看Real World Haskell 中的Bloom Filter示例,但发现我实际上无法使我的代码在runST中运行.
我的数据结构,首先是纯数据,然后是不纯的:
import Data.Vector.Unboxed (Vector)
import Data.Vector.Unboxed.Mutable (MVector)
data PixelMap = Bitmap Int Int (Vector Bool)
data MPixelMap s = MBitmap Int Int (MVector s Bool)
Run Code Online (Sandbox Code Playgroud)
然后我只创建一个基本的newBitmapM函数:
newBitmapM :: (Int, Int) -> ST s (MPixelMap s)
newBitmapM (width, height) = MBitmap width height `liftM` MV.replicate (width * height) False
Run Code Online (Sandbox Code Playgroud)
这加载到GHCI就好了,但后来我尝试运行它:
> runST $ newBitmapM (15, 15)
<interactive>:78:9:
Couldn't match type `a' with `PixelMapMutable s'
`a' is a rigid type variable bound …Run Code Online (Sandbox Code Playgroud) 对于一年多以来,我一直在用强烈lift,return和构造等EitherT,ReaderT等.我读过Real World Haskell,Learn You a Haskell,几乎每个monad教程,并尝试编写自己的.然而,我经常对这三项行动感到困惑.每当我编写新代码时,我都会尝试找出三个中的哪一个使用,而且在特定代码块中的第一个函数上几乎总需要一个小时或更长时间.
什么是三者的直观理解?简单的类型是不够的,因为在所有三种情况下我都可以立即背诵你的类型.什么是这些是什么含义做的是在所有标准单子变压器的一致?
(不幸的是,如果你用数学术语回答,我仍然不会理解你.虽然我可以编写代码来解决数学问题,并且可以根据我看到的代码设置时间复杂度,但是经过多年努力,我不能Haskell的工作将数学术语与编程术语联系起来.)