【问题标题】:Boolean check in Haskell when assigning IO action to variable将 IO 操作分配给变量时在 Haskell 中进行布尔检查
【发布时间】:2015-03-29 02:18:08
【问题描述】:

我不确定这是否可能,但我希望能够执行一个返回值的 IO 操作,如果它被分配给一个变量,那么它会抑制特定的 IO 操作(或者当,任何动作,我猜,它不一定是 IO 动作)。

这是我遇到的具体问题:

当我这样做时:

renderDrawable drawable

我希望它调用特定函数 (drawArrays)。

赋值给变量时,比如:

d <- renderDrawable drawable

我希望抑制该特定功能。

现在,这似乎是一个遥远的目标,但有可能吗?我猜,类似于 mapM_/foldM_ 的东西是理想的。

谢谢!

【问题讨论】:

  • “被压制”是什么意思?
  • 最接近此的方法是区分返回类型,以便在返回 IO () 时执行某些操作,而在返回 IO TypeOfd 时执行其他操作。然而,这需要一个类型类,即使这样也可能需要调用者代码中的一些类型注释。那么,为什么不直接定义两个不同的函数呢?
  • 也许更详细地描述你试图从更高层次的角度实现的目标。出于充分的理由,您所要求的在 Haskell 中是不可能的,但可能还有其他更好的方法。
  • 我认为您所要求的内容在任何其他语言中也不可能,如果我理解正确的话,这真的很奇怪......
  • 是的,我不认为是这样,但有几件事让我对 Haskell 的能力感到惊讶。从本质上讲,我想要的是一个 if 语句来确定我是否调用一个函数,基于原始函数的调用方式,如果这有意义?

标签: haskell io return variable-assignment


【解决方案1】:

你所要求的在 Haskell 中是不可能的。 Haskell 设计背后的基本规则之一是compositionality:表达式的含义完全取决于其子表达式的含义以及它们的组合方式。 唯一的例外是变量的含义取决于上下文。

从根本上说,您所要求的是让renderDrawable drawable 表示两个不同的东西,具体取决于它在程序中出现的上下文(在这种情况下,取决于它的结果是否绑定为变量)。没办法。

组合性与 Haskell 的设计也遵循的参照透明纯度原则密切相关。不仅仅是 Haskell 的设计重视组合性,因为通常大多数编程语言在大多数情况下都遵循它。否则很难对代码进行推理。

我能想到的最接近您正在寻找的是这之间的对比:

do {- ... -} 
   renderDrawable drawable
   {- ... -}

还有这个:

do {- ... -} 
   let d = renderDrawable drawable
   {- ... -}

如果您不熟悉let 的这种形式,那么您可以将纯值 分配给do-notation 内的变量。您在这里所做的是获取renderDrawable drawable,并将动作本身(不是其结果!)绑定到变量d。这只是一个变量赋值,所以renderDrawable drawable不会被执行。

【讨论】:

  • 啊,我以前从未尝试过使用 let 绑定返回 IO 的函数。不过,我不确定我是否可以使用它。因为结果是某物的最终状态。如果我将d 传递给它,它将是对象的IO,然后我需要在函数中使用&lt;- 来绑定它,这意味着它每次调用它时都会重新计算状态是我一开始就想避免的。没关系,我只需要一个 bool 参数或一个单独的函数。谢谢!
【解决方案2】:

虽然这个答案可能不如上面的那么好,因为就像他们说的那样,这是不可能的,我找到了另一种方法。

drawDrawable 是一个递归函数。 Drawable 是我的数据类型,因此我为 Drawable 添加了另一个节点。它需要另一个 Drawable 作为参数,以及向下遍历的当前状态,如果我希望它呈现,只需将标志设置为 true。所以我会有类似的东西

drawDrawable Direct drawable

不过,这似乎可能是错误的来源。所以我选择了单独的函数:compilerender,其中render 返回一个IO () 而不是IO Drawable,就像工作一样

render :: Drawable -> IO ()
render drawable = do
  cd <- compile drawable
  renderCompiled cd

完成这项工作,整个情况的歧义就更少了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 2018-03-15
    • 2012-06-20
    • 2023-04-03
    • 2019-10-19
    • 2011-11-28
    相关资源
    最近更新 更多