“ pure x :: IO a”是纯值还是具有副作用的值?

时间:2019-01-08 22:01:43

标签: haskell side-effects

给予

pure id <*> v = v

可以,pure可以做任何可观察到的事情并且不违反法律吗?

如果我定义一个封装IO的类型并说产生一个新线程,那么GHC可以自由地优化它吗?

2 个答案:

答案 0 :(得分:5)

GHC对类型类定律一无所知(与Idris或Coq不同),这些定律仅作为文档和编程约定存在。因此,实例可以是合法的,也可以是非法的,无论哪种情况,GHC优化都不会改变程序的行为。

如果您编写了一个特定的合法实例,则可以添加一个REWRITE规则以使GHC删除pure id,并且GHC最终还可以针对特定的{ {1}}仿函数,这种优化的安全性显而易见。

答案 1 :(得分:2)

我必须将您的问题分为两个问题:

  

pure x :: IO a是纯值还是有副作用?

实际上是纯值。在此代码中,x的类型为a,这是一个纯值。
pure的类型为a -> IO a,它用IO包裹了参数,但实际上没有任何副作用。
因此,pure x :: IO a的类型似乎有副作用,但实际上没有。

  

...纯粹可以做任何可观察到的事情而不会违反法律吗?

不。 pure仅将id应用于由v引起的副作用的结果。
只要实例遵循适用法律,就会引起副作用的不是pure而是v

我想您以x中的pure xv :: IO a中的pure id <*> v
前者是一个完全纯净的值,其类型为a,后者不是一个纯净值:一种操作,该操作可能导致副作用,返回一个类型为a的值。

最后一个问题:

  

如果我定义一个封装IO的类型并说产生一个新线程,GHC可以自由地对其进行优化吗?

对不起,我不确定优化。