【问题标题】:Functions submitted lazily懒惰提交的函数
【发布时间】:2019-01-27 15:03:15
【问题描述】:

我在学习 Paul Chiusano 和 Runar Bjanarson 所著的“Scala 中的函数式编程”一书(第 7 章 - 纯函数式并行)时遇到了这个函数定义:

 def fork[A](a: => Par[A]): Par[A] = 
    es => es.submit(new Callable[A] {
      def call = a(es).get
    })

Par[A]type Par[A] = ExecutorService => Future[A]ExecutorServiceFuture 来自 java.util.concurrent 库。 Here 是 Github 上的完整代码。有关java.util.concurrent 文档,请参阅here

我的问题是提供一个函数作为惰性参数意味着什么?特别是,我可以理解延迟提供计算意味着什么,但我无法理解它在函数的情况下意味着什么?

【问题讨论】:

    标签: scala parallel-processing lazy-loading lazy-evaluation


    【解决方案1】:

    提供一个函数作为惰性参数

    对于fork 函数有一个惰性参数a: => Par[A],这意味着afork(a) 被提交到ExecutorServiceCallable 之前不会评估,因为a 的响应类型还有Par[A],它也会再次异步eval,也可以递归 fork 用相同的ExecutorService执行。

    所以据我了解,fork 带有 惰性参数 a: => Par[A],它将具有并行和递归分叉任务的能​​力。


    Scala中,惰性函数:意思是惰性求值,直到调用这个函数。对于您的示例,您正在声明一个 惰性函数 a: => Par[A],因此当您调用 fork 方法时,例如:fork(myFunction()),这不会立即评估 myFunction,它只会在 @ 时评估987654335@被执行。

    例子:

    def fun(a: => Int): Int = {
      println("second run")
      a
    }
    
    def fun2(): Int = {
      println("first run")
      1 + 1
    }
    
    fun(fun2())
    

    上面的代码会输出如下:

    第二次运行

    第一次运行

    因为提交fun2() 作为lazy function 不会被fun(fun2()) 评估,它将在方法fun 中评估。

    【讨论】:

    • 这根本没有解决问题。问题是关于 => (ExecutorService => Future[A]) 作为输入类型。
    • 是的,在这种情况下看到它会很有帮助。但是,@chengpohi 的回答也帮助了我。特别是,如果 fun 没有懒惰地接受它的论点,那么我们会在“第二次运行”之前看到“第一次运行”,对吗?
    • @AndreyTyukin@clog14 抱歉误解了这个问题:(,我已经更新了我的答案,希望对您有所帮助。
    • @chengpohi 非常感谢您使这一点更加精确。但是,我还是觉得有点不确定。你能解释一下如果函数不接受它的参数会发生什么?
    • @clog14,如果不接受它的参数,它会立即eval,例如:fork(a) + fork(b),这两个fork函数不能并行运行,它会顺序运行,如果我们让参数是惰性的,fork 可以并行运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2012-02-20
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    相关资源
    最近更新 更多