用于跟踪副作用的 Monad

Monad for tracking side-effects

在Haskell中,我们有IO monad来处理副作用,虽然,它不能表达地跟踪副作用,你真的不知道是什么类型的副作用真的发生了:

main :: IO ()

在 PureScript 中,我们有 Eff monad,您可以根据类型签名知道发生什么类型的副作用:

main :: forall e. Eff (fs :: FS, trace :: Trace, process :: Process | e) Unit

这里很明显 main 函数使用了文件系统,跟踪消息到控制台并且能够处理当前进程,我们有一个特定的模块 Control.Monad.Eff处理副作用,以及 Control.Monad.Eff.RandomControl.Monad.Eff.Console.

等子模块

以下举例:

module RandomExample where

import Prelude

import Control.Monad.Eff
import Control.Monad.Eff.Random (random)
import Control.Monad.Eff.Console (print)

printRandom :: forall e. Eff (console :: CONSOLE, random :: RANDOM | e) Unit
printRandom = do
  n <- random
  print n

这比仅使用 "Hey, here happens a side-effect, that's it, no more that you need to know!" 要具体得多。我一直在浏览网络,但没有看到足够完整的 monad 来跟踪副作用。

Haskell 中是否有特定的 monad,如 Eff,用于跟踪副作用?

提前致谢。

有几个库为 Haskell 定义了类似的效果系统。

我用 extensible-effects 工作过一些,发现添加受限制的 IO,例如 STDIOFileIO 效果非常容易。缺少编译器支持使得使用起来不太好。

如果您想尝试一下,可以从 extensible-effects 框架的现有效果中找到灵感:http://hackage.haskell.org/packages/#cat:Effect

似乎有一个 extensible-effects 版本不使用 Typeable 来跟踪效果:http://hackage.haskell.org/package/effin。这样应该可以更好地编写新效果。