在Haskell术语中,什么是单子效应?

5

我觉得我对单子有一个很好的理解,但是我不太确定“单子效应”指的是什么?这是单子的评估吗?这与IO有关吗?


Effect是单子的计算策略的俗称。例如,Identity单子并不追求特定的策略。它只执行普通的函数应用而没有任何修改。 - user6445533
2个回答

15
如果您有一个类型为M a的值,其中MMonad(或者对于applicative效果是Applicative),那么所谓的效果是指不包含在a部分中的信息。例如,在IO中非常清楚。一个IO Int类型的值是带有一些IO效果的Int值,如写入文件或发射导弹。而类型为Maybe Int的值是带有可能并不包含Int的效果的Int值。对于[Int],效果是您实际上拥有多个Int
我们称这为效果,因为您可以将Monads和Applicatives视为具有某些效果的计算概念。对于Maybe,效果是您可以提前终止计算;对于[],效果是您可以拆分计算。

2
我不喜欢这个“IO Int的值是带有一些IO效果的Int”的措辞。一个IO Int并不比ls是文件列表更像一个Int。更准确地说,将其称为生成Int的配方会更加准确。 - Rein Henrichs

3
我将尝试以几种方式来讲解这个问题,希望对您有所帮助。
“效应”(如“副作用”)是指Monad的一个特定实例的行为,因此,例如,State monad通过getput表达了“有状态计算”的效应。像mtl这样的monad transformer库可以被视为“组合效应”的方法。
在不知道foobar的类型(或者事实上没有阅读文档)的情况下,我们无法确定这里发生了什么“monadic effects”,即使我们可以说出关于这段代码的很多其他内容。
do a <- fmap bar $ foo x
   b <- baz
   return (a,b)

上面的do块的类型形式为SomeMonad m=> m (a,b)。这个被“返回”的元组(a,b)以及它可以通过>>=传递给另一个“有副作用的计算”方式,不是我们谈论“效果”时所说的内容。
当您运行它们(例如调用StaterunState)时,单子效果总是实际发生的。
IO的情况下,只有运行时才能访问特定的run函数,因此不存在的runIO函数调用main来运行您的程序。对于IO,“单子效应”确实与其他语言中称为“副作用”的内容相同,即几乎可以改变世界状态的任何事情。

1
Maybe 会有任何单子效应吗?它没有任何 run 方法,这会增加一些混淆。 - Chris Stryczynski
你说得对,我差点在考虑到Maybe[]的情况下回去编辑,但是我没有一个好的快速澄清方法(但是那句话肯定不太准确)。Maybe表达了可能失败的计算效果(或者在具有null的语言中进行计算)。 - jberryman

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