Scalaz-可运行单子

Scalaz-可运行单子,scala,monads,scalaz,Scala,Monads,Scalaz,Scalaz中是否有“可运行”单子的概念一个可以从中提取结果值,潜在的隐藏副作用 trait RunnableM[M[_]] { def runM[T](m: M[T]): T } 我需要这个来评估一元计算,并在最后退出一元计算。在Haskell中,我们为monad提供了不同的“run”函数,这些函数可能涉及IO,也可能不涉及IO,所以至少在我看来,这样的类型类可能是不可能的。但在Scala中,这是可以做到的。不是一个“正确”的解决方案,但scalaz的Comonad具有copoint,可

Scalaz中是否有“可运行”单子的概念一个可以从中提取结果值,潜在的隐藏副作用

trait RunnableM[M[_]] {
  def runM[T](m: M[T]): T
}
我需要这个来评估一元计算,并在最后退出一元计算。在Haskell中,我们为monad提供了不同的“run”函数,这些函数可能涉及IO,也可能不涉及IO,所以至少在我看来,这样的类型类可能是不可能的。但在Scala中,这是可以做到的。

不是一个“正确”的解决方案,但scalaz的
Comonad
具有
copoint
,可以(ab)用于实现这一点
Comonad
实例已经存在于许多标准scalaz Monad中,您可以欺骗并定义一个实例,例如,
任务
(这可能会让理论家生气;确保将任何此类实例的范围限制在您需要的地方,并为IO的发生感到高兴,不要让它感染远程代码)。它被添加到实例上:

def runM[T](m: M[T])(implicit cm: Comonad[M]) = m.copoint

我只是为了测试的目的才需要这个。我对Comonad了解不多-这是它的主要目的吗?要从单子中提取值?它的主要目的是合成shape
M[A]=>B
的函数。过去(在Scalaz6中)有一个独特的
Copoint
类型,只用于提取您想要的值,但它被放弃了;托尼·莫里斯(Tony Morris)对这个坏主意大喊大叫,但没有解释实际问题是什么,所以我不知道为什么。(如果我不得不猜测的话,我会想象这样的论点是,
Copoint
是非法的,所以你不可能用它写任何有用的东西,因为你不知道它对泛型
M
有什么影响)。