使用IO monads编写大部分代码是否可以

use*_*906 8 monads haskell

我正在尝试使用Haskell开发聊天服务器.

有很多像有用的工具TChan,TSkiplist,forkIO...等等,但事实证明,我的大部分代码是IO单子和unsafePerformIO,这听起来非常低效里面写.

这样做是否可以,或者haskell不是用于此目的的正确工具?

And*_*ewC 19

作为一般规则,尝试首先将代码编写为纯函数,而不必担心数据来自哪里 - 只是假设它在那里.

接下来将IO中的纯功能包装起来,以提供纯函数数据并将结果放在某处.可以在聊天应用程序中进行很多这样的操作!IO monad根本不是低效的,只是我们更愿意保留尽可能多的代码,因为这是好的设计 - 保持数据与IO分开.聊天应用程序不会对其获得的数据进行大量计算,因此可以使用大量IO代码.

我认为坚持IO monad比使用unsafePerformIO更好,因为unsafePerformIO将其结果呈现为纯数据.我可能很想用它来从配置文件中获取常量,但我从来没有真正这样做过,如果你在IO monad中大量使用它也没有意义.有一个原因,它被称为不安全!PetrPudlák在下面的评论中提出了很好的建议.

我听说Haskell的monad被描述为世界上最好的命令式编程语言.我可以分开描述,但我同意这种观点,是的,坚持使用Haskell.Haskell擅长于你正在使用它的编程.

  • 好答案.只是我主张更强烈反对使用`unsafe*`.使用`unsafe*`会让你失去Haskell强制执行的东西 - 分离纯粹和不纯的计算.结合懒惰的评价,"不安全*"会让你的生活变得悲惨. (4认同)
  • 实际上并不是*特定*中的*IO*monad被引用; Haskell被认为是"最好的命令式编程语言",因为你可以决定*哪种*命令式语言:IO语言,非决定论语言,国家语言,这些东西的组合等等.这有时被称为"可编程分号". (3认同)

Pet*_*ter 12

每当你注意到你有一个长函数驻留在IO monad中时,暂停并查看发生的计算是值得的.根据我的经验,(几乎)总是这样的情况,即一些非IO相关的东西正在进行,不需要访问输入输出,可以封装在函数中.

这有一个很大的优势,它迫使您从输入/输出处理中找到适当的抽象和单独的(纯)算法.而且,验证和测试纯函数要容易得多.当然,你仍然会在某些IO a函数中调用这些纯函数(例如main),但这完全没问题.


Dan*_*ton 5

我的大多数代码都是在IO monads中编写的

没关系.

和unsafePerformIO

那很糟!避免unsafePerformIO像瘟疫一样使用; 它应该只在经过特殊情况下由资深Haskellers使用.

这样做是否可以,或者haskell不是用于此目的的正确工具?

可以在IO monad中编写代码,但不能正常使用unsafePerformIO.相反,学习如何使用Monad接口(do符号)组合IO操作.了解哪些功能类型签名需要包含IO类型.

  • @ user1748906如果您勾选类型签名[STM a - > IO a](http://www.haskell.org/hoogle/?hoogle=STM+a+-%3E+IO+a),第一个命中是`原子地`,正如Ptharien的火焰所暗示的那样. (3认同)
  • 避免使用unsafePerformIO!如何在io monads中启动stm事务? (2认同)
  • @ user1748906使用`atomically`. (2认同)