由于Haskell的数据是不可变的,你如何全局存储一个可以被任何函数修改的列表?你是否可以将它读取并存储在循环中?或者将列表写入文件? 我需要记录用户点击的按钮数量。
答案 0 :(得分:12)
一般情况下,正如你所说的那样,Haskell的数据(大多数)是不可变的。
如果您要从列表开始并通过一大堆更新函数运行它,则每个函数都将列表作为参数并返回更新的列表作为结果。然后你有一些协调功能(可能main
,如果这是你的所有程序正在做的事情),它将每个更新的输出提供给下一个更新程序。
可以使用State monad之类的东西来使用隐式状态更新进行编程,或者使用IO Monad中的ST monad或IORefs中的STRef进行编程,使用可以实际更新的隐式状态更新就地的东西。但是Haskell程序员通常不希望将大部分程序放在这样的monad中,以便对可写值进行隐式全局访问。
答案 1 :(得分:2)
您将使用状态monad(或io monad,ST monad或其他类似的东西)。或者,您可以将其作为参数传递给每个函数,并从每个函数返回新值(这是各种monad为您所做的)。
如果不使每个需要状态的函数使用monad,就没有办法拥有全局可变状态。这是Haskell设计者的有意选择 - 每个非monadic函数都需要在引用上是透明的(这意味着函数总是为给定的一组输入返回相同的值)并且如果有可变的状态可以从一个非monadic函数,它可以返回可变状态并违反引用透明度。
从技术上讲,monadic函数也是引用透明的 - 即使模拟副作用的函数也可以通过获取并返回一个额外的world参数(隐藏为monad的一部分)来实现这一点。