Haskell - "IO()"是否意味着我们放弃对程序的控制?

sno*_*ntw 1 haskell functional-programming

我们知道在Haskell程序中,几乎每一个计算都会返回一些东西,并且这些返回值可以通过另一个计算来捕获,以对其应用更多的变换.因此,如果我们"平坦化"正常的Haskell程序,它应该是:

-- pure `a`: comes from Hask; not from file, network or any 
-- other side-effected devices

a ? a' ? a'' ? a''' ? .... ? a_fin
Run Code Online (Sandbox Code Playgroud)

当然,这种纯粹的价值可能是"背景的".但我们仍然可以追踪交替的道路:

a ? m a ? m a' ? a'' ? n a''' ? ... ? z a_fin
Run Code Online (Sandbox Code Playgroud)

对我来说,这表明我们可以控制我们的程序,以避免副作用和其他"惊喜",这可能是由于缺少类型系统或我们自己造成的.但是当IO ()出现时,似乎有一个缺失:

--!! What happened between the IO () and the next computation ?

a ? m a ? m a' ? IO () >> b ? b' ? m b'  
Run Code Online (Sandbox Code Playgroud)

IO ()似乎传递/接收什么,但它必须读/至少写的东西.特别是如果我们考虑"接收器"过程:

Sender::   a ? m a ? m a' ? IO () >> b ? b' ? m b' ... ? m b_fin
Receiver:: IO a' ? IO a'' ? IO a''' ? ... ? IO a_fin
Run Code Online (Sandbox Code Playgroud)

在发件人中,我们无法看到a之后发生的事情IO ().但如果我们考虑这两个过程,那么缺失的部分又回来了!因此,根据您的观点,我们可以说我们错过了或者没有错过这些信息.这是一个信息泄漏,当我们把它放入程序时,我们只是放弃对我们程序的控制IO ()

谢谢 !

PS.哦,我还发现接收器,只能用"上下文"值开始计算,而不是纯值,这是另一个问题出现在我的脑海里......

Vla*_*eev 7

从您的评论中看起来您认为因为IO ()有条件的计算没有返回有用的类型系统无法保证您的程序是正确的.

首先,除简单情况外,类型系统保证程序的正确性.在复杂的程序中,完全有可能出现逻辑错误,程序将编译但返回错误的结果.程序员有责任避免逻辑错误,而类型系统只是一个(确实是功能强大的)工具.

第二点从第一点开始.IO是一个普通的单子; 它与任何其他类型(从类型系统的角度来看)是相同的类型.AFAIK它没有从类型系统中获得一些特殊处理.类型的值IO ()确实意味着"不纯的计算,当执行时,可能以某种方式影响外部世界,并且不会产生任何有意义的东西",仅此而已.考虑类型的值State Int ():它意味着'一个有状态的计算,当执行时,它可以用当前的类型状态做某事Int并且不产生任何有用的东西'.你看,这两个值都有某种副作用,它们都具有与计算结果相同的含义.从类型系统的角度来看,它们是这样的.但第二个是完全纯粹的计算.您可以Int使用execState或轻松将其转换为某个有意义的值(在本例中)runState.