Haskell中的并行性

5

我正在尝试创建一个简单的示例来进行并行评估:

import Control.Parallel.Strategies

main = do
  runEval $ do
    a <- rpar (\x -> x + 5)
    b <- rseq (\x -> x + 15)
    return (a, b)

它说:

Couldn't match expected type `IO t0'
                with actual type `(Integer -> Integer, Integer -> Integer)'

我知道这与Haskell中的并行无关,但不管怎样,我该如何在Haskell中构建这样一个简单的例子呢?

1个回答

2

问题出在你使用lambda的方式上。 rparrseq 的类型是 a -> Eval a,但是你传递的lambda显然是 Integer -> Integer 类型,因为你没有将参数传递给lambda。

下面这样编写可以编译通过(还要注意需要打印结果):

main = do
    print $ runEval $ do
        a <- rpar $ (\x -> x + 5) 4
        b <- rseq $ (\x -> x + 15) 4
        return (a, b)

如果想了解Haskell中的并行处理,可以看一本名为《Parallel and Concurrent Programming in Haskell》的好书,作者是Simon Marlow。你可以在这里免费获取HTML版本:


顺便问一下,为什么在 runEval $ do 中使用 "$" 是必要的? - Incerteza
1
@Alex,$被称为应用运算符,它的存在主要是为了消除括号。f $ xf (x)等价,而g $ f $ x等价于g (f (x))。它的右侧所有内容都会被括号包裹起来,并传递给左侧的表达式。 - bheklilr
@Alex 如果你是Haskell的新手,我建议你阅读《Learn you a Haskell for Great Good!》,它也可以在线获取:http://learnyouahaskell.com/chapters - Rodrigo Taboada
实际上,这完全是 Haskell 语法的一部分。do 块不能在任何表达式上下文中使用 - 只能作为表达式中的第一件事。但是,所有二元运算符都将它们的每个参数视为完整的表达式,因此您可以将一个 do 块放在其右侧。 - Carl
2
@Alex 表达式 do { a <- rpar $ (+5) 4; b <- rseq $ (+15) 4; return (a, b); }$runEval 之间被传递为单一的参数。没有 $,编译器会把它看做是 do {print $ runEval do; ... },其中 dorunEval 的唯一参数。如果你定义了一个等价于内部 do 块的独立函数:f = do { a <- rpar $ (+5) 4; b <- rseq $ (+15) 4; return (a, b); },那么 main 可以简单地写成 print $ runEval f - bheklilr
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接