我最近开始阅读 Go 编程语言,发现通道变量是一个非常吸引人的概念。是否可以在 Haskell 中模拟相同的概念?也许有一个数据类型Channel a
和一个单子结构来启用可变状态和像关键字一样工作的函数go
。
我在并发编程方面不是很好,像 Haskell 中这样的简单通道传递机制真的会让我的生活更轻松。
编辑
人们要求我澄清我有兴趣将哪种 Go 模式转换为 Haskell。所以 Go 有一流的通道变量,可以通过函数传递和返回。我可以读取和写入这些通道,因此可以在可以同时运行的例程之间轻松通信。Go 还有一个go
关键字,根据语言规范,它作为一个独立的线程同时启动一个函数的执行,并继续执行代码而无需等待。
我感兴趣的确切模式是这样的(Go 的语法很奇怪 - 变量由 varName varType 声明,而不是通常的反转方式 - 但我认为它是可读的):
func generateStep(ch chan int) {
//ch is a variable of type chan int, which is a channel that comunicate integers
for {
ch <- randomInteger() //just sends random integers in the channel
}
func filter(input, output chan int) {
state int
for {
step <- input //reads an int from the input channel
newstate := update(state, step) //update the variable with some update function
if criteria(newstate, state) {
state = newstate // if the newstate pass some criteria, accept the update
}
output <- state //pass it to the output channel
}
}
func main() {
intChan := make(chan int)
mcChan := make(chan int)
go generateStep(intChan) // execute the channels concurrently
go filter(intChan, mcChan)
for i:=0; i<numSteps; i++ {
x <- mcChan // get values from the filtered channel
accumulateStats(x) // calculate some statistics
}
printStatisticsAbout(x)
}
我的主要兴趣是进行蒙特卡罗模拟,其中我通过尝试修改系统的当前状态并在满足某些标准时接受修改来顺序生成配置。
使用这些通道的东西,我可以编写一个非常简单、可读且小型的蒙特卡罗模拟,该模拟将在我的多核处理器中并行运行,这让我印象深刻。
问题是 Go 有一些限制(特别是,它缺乏我在 Haskell 中习惯的方式的多态性),除此之外,我真的很喜欢 Haskell,不想把它换掉。所以问题是是否有某种方法可以使用一些类似于上面代码的机制来轻松地在 Haskell 中进行并发模拟。
编辑(2,上下文): 我没有学过计算机科学,特别是在并发方面。我只是一个创建简单程序来解决我日常研究程序中的简单问题的人,该学科与 CS 完全无关。我只是觉得 Haskell 的工作方式很有趣,并且喜欢用它来做我的小家务。
我从未听说过单独的 pi-calculus 或 CSP 通道。抱歉,如果这个问题看起来不恰当,这可能是我对此事的巨大无知的错。
你是对的,我应该更具体地说明我想在 Haskell 中复制的 Go 模式,我会尝试将问题编辑得更具体。但不要指望深刻的理论问题。问题是,从我阅读和编码的一些东西来看,Go 似乎有一种巧妙的方式来实现并发(在我的情况下,这只是意味着我的工作让我的所有核心都在数值计算中嗡嗡作响),并且如果我可以在 Haskell 中使用类似的语法,我会很高兴。