【问题标题】:Is it ok to write most of the code using IO monads大部分代码都可以用 IO monads 写吗
【发布时间】:2012-10-16 04:51:52
【问题描述】:

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

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

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

【问题讨论】:

  • 看看Hulk - 开始在 Haskell 中编写 IRC 服务器。

标签: haskell monads


【解决方案1】:

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

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

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

我听说 Haskell 的 monad 被描述为 best imperative programming language 在 世界。我可以对这种描述感到震惊,但我同意这种观点,是的, 坚持使用 Haskell。 Haskell 擅长于您使用它的编程。

【讨论】:

  • 好答案。只是我会更强烈地反对使用unsafe*。使用 unsafe* 会让你失去 Haskell 强制你的东西——分离纯计算和不纯计算。再加上懒惰的评价,unsafe*会让你的生活变得悲惨。
  • 好点。我已经加强了反对不安全的建议,但我留下了关于懒惰+不安全的观点以供您发表好评论。
  • 它并不是真正被引用的 particular 中的 IO monad; Haskell 被称为“最好的命令式编程语言”,因为你可以决定它是哪种命令式语言:具有 IO 的语言、具有非确定性的语言、具有状态的语言、这些东西等等。这有时被称为“可编程分号”。
  • @Dan You 提出了一个很好的当代观点,但在原始论文 Tackling the Awkward Squad 中,Simon Peyton Jones 以“简而言之,Haskell 是世界上最好的命令式编程语言”结束了他的介绍。在之前说过“确实,IO monad 是这些笔记的统一主题”之后,它真的只是关于 IO monad; SPJ 特别指的是 IO monad,但我同意有更广泛的好处。 Applicative Functor 是我在命令式代码中最喜欢的构造。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    没关系。

    和 unsafePerformIO

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

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

    可以在 IO monad 中编写代码,但不能使用 unsafePerformIO。相反,学习如何使用Monad 接口(@98​​7654325@ 表示法)编写 IO 操作。了解哪些函数类型签名需要包含IO 类型。

    【讨论】:

    • 避免使用 unsafePerformIO !如何在 io monads 中启动 stm 事务?
    • @user1748906 使用atomically
    • @user1748906 如果你 hoogle 类型签名STM a -> IO a,第一个命中是atomically,正如 Ptharien's Flame 所建议的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多