0

当我在阅读SDLhaskell的文档时,我发现一些函数不可避免地会修改它的输入。例如,blitSurface将目标表面作为输入,但在函数内更新。现在,概括问题,如果我有一个函数f :: a -> IO a,如果我在函数内部修改它会破坏组合a吗?怎么样f :: IO a -> IO a?怎么样a -> IO ()?那么IO a -> IO ()呢?

考虑到blitSurface实际上是一个外来函数的情况,并且每帧制作一个新曲面听起来效率不高,这些函数是难以避免的。这样的功能会导致更大范围的问题吗?例如,以fModifySurface :: Surface -> IO ()which does 破坏性更新为例:

main = do
    w <- ... -- The window surface
    -- Do something here
    s <- someFuncGetSurface -- We get a surface here
    fModifySurface s -- Destructively update s
    blitSurface ...... -- Ignore the actual API, but destructively updates w

上面的代码中是否有任何意想不到的语义?如果是这样,利用改变输入的外部函数的最佳方法是什么?

4

1 回答 1

5

我观察到这一点,f a b并且flip f b a是等价的术语。另一方面,这些的直接IO版本,即f <$> a <*> bflip f <$> b <*> a,当然不是 beta 等价的;甚至使用“解决尴尬小队”中的等价词,这使得更多的IO动作等价,这两个术语并不等价。

在高层次上,这意味着如果你证明了关于纯项的行为的某些东西,那么即使将纯计算用作更大程序的一部分,你也可以重新使用该证明。另一方面,没有相应的方法将关于一个IO术语的本地证明统一提升为关于更大IO程序的证明;如果您希望这样做,您必须调用一些关于您计划一起使用的特定操作的全局属性。IO

这是将尽可能多的计算从IO纯粹世界中提升出来的常见建议背后的推动力——事实上,它是首先进行纯函数式编程的主要动机之一,即命令式程序作曲不好。

但是,这些讨论都不是特定于 FFI 或其IO操作更新其输入之一引用的值的函数。blitSurface在这方面,基本上不比我们扔进的任何“罪恶箱”更差或更好IO。命令式程序根本不像纯程序那样具有组合性。

于 2015-10-06T01:57:46.480 回答