8

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

有很多有用的工具,比如TChan, TSkiplist, forkIO...等等,但事实证明,我的大部分代码都是写在 IO monads 和 unsafePerformIO 中,这听起来效率很低。

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

4

3 回答 3

19

作为一般规则,首先尝试将代码编写为纯函数,而不用担心数据来自哪里——只要假设它就在那里。

接下来将纯函数包装在 IO 中,以提供纯函数数据并将结果放在某处。聊天应用程序中有很多这样的事情没关系!IO monad 一点也不低效,只是我们更喜欢尽可能多地保留代码,因为这是一个很好的设计——让数据处理与 IO 分开。聊天应用程序不会对其获取的数据进行大量计算,因此可以有大量的 IO 代码。

我认为坚持使用 IO monad 肯定比使用 unsafePerformIO 更好,因为 unsafePerformIO 将其结果呈现为纯数据。我可能很想用它从配置文件中获取常量,但我从来没有真正这样做过,而且如果你在 IO monad 中很忙,那也没有意义。它被称为不安全是有原因的!Petr Pudlák 在下面的评论中有很好的建议。

我听说 Haskell 的 monads 被描述为世界上最好的命令式编程语言。我可以在那个描述上分裂头发,但我同意这种观点,是的,坚持使用 Haskell。Haskell 擅长于您使用它的编程。

于 2012-10-16T06:20:01.273 回答
12

每当你注意到你有一个长函数驻留在 IO monad 中时,停下来看看发生的计算是值得的。根据我的经验,(几乎)总是发生一些与 IO 无关的事情,这些事情不需要访问输入输出并且可以封装在函数中。

这有一个很大的优势,它迫使您找到适当的抽象并将(纯)算法与输入/输出处理分开。此外,验证和测试纯函数要容易得多。当然,您仍然可以从某个IO a函数(例如main)中调用这些纯函数,但这完全没问题。

于 2012-10-16T05:19:59.473 回答
5

我的大部分代码都写在 IO monads 中

没关系。

和 unsafePerformIO

那很糟!避免unsafePerformIO像瘟疫一样使用;它应该只在非常特殊的情况下由经验丰富的 Haskellers 使用。

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

在 IO monad 中写代码是可以的,但使用unsafePerformIO. 相反,学习如何使用Monad接口(do符号)组合 IO 操作。了解哪些函数类型签名需要包含该IO类型。

于 2012-10-16T14:46:09.440 回答