用于跟踪副作用的Monad

8
在 Haskell 中,我们有 IO 单子用于处理副作用,但它不能表达副作用,并且你不知道真正发生了什么类型的副作用。
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

这比仅使用"嘿,这里发生了一个副作用,就这样,你不需要知道更多!"要具体得多。我在网上搜索过,没有看到足够完整的单子来跟踪副作用。

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

谢谢您提前。


1
有各种副作用,你想要哪一个?其中一些有自己的单子(State等),许多库引入了更多的单子(Yesod等),但我猜你不能像在PureScript中那样组装它们,通常需要使用transformers和monad-stack概念来完成这个过程。 - Random Dev
一个小问题:IO效果,而不是副作用。副作用会是一些邪恶的事情,比如通过unsafePerformIO进行 I/O 的计算假装是纯洁的。 - Cactus
1个回答

4
有几个库为Haskell定义了类似的效果系统。
我已经使用过 extensible-effects,并发现它很容易添加限制性的IO,例如STDIOFileIO,效果。 缺乏编译器支持使其使用起来略显不便。
如果您想尝试它,则可以从extensible-effects框架的现有效果中获取灵感:http://hackage.haskell.org/packages/#cat:Effect 似乎有一个版本的extensible-effects不使用Typeable来跟踪效果:http://hackage.haskell.org/package/effin。 这应该使编写新效果更加方便。

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