Haskell 的纯度是由类型系统还是 IO 的实现强制执行的?
Is Haskell's purity enforced by the type system or IO's implementation?
人们总是说 Haskell 的类型系统可以防止不纯代码污染纯代码,因为您总是必须在类型签名中指定 IO
。但是,这是类型系统本身的结果,还是真的只是 IO(..)
没有导出?
基本上,如果类型构造函数可用,是否可以完成类似的事情?
ioToPure :: IO a -> a
ioToPure (IO ioValue) = ioValue
是的,这在某种意义上是正确的。
类型系统本身对 IO
一无所知,也不需要。不同的语言特性向用户隐藏了 IO 操作的真实表示,因此不可能 "just run" IO 操作。
所以,事实是,Haskell 和类似语言的 IO 安全性是多种语言特性和属性的综合结果,最突出的是:
- 不接受用户 "shut up, I know better" 的强类型系统。
- 一切都是打出来的属性。我在这里的意思是,在不纯的语言中,你有 "statements" 并且即使类型系统很强大,它也不会超过下一个分号。而在 Haskell 中,我们只有表达式,每个表达式的每一位都有一个类型,并最终影响表达式所在函数的类型。
- 隐藏类型表示的语言特性。
尽管如此,我认为表达式 "the type system makes sure that impure and pure code is separated" 是一种无害的简化。
当然,导出低级基元可能会在任何地方产生副作用。
而且,是的,你可以通过避免出口每一种危险的东西来获得纯度仅。不需要类型级机器。
但是,如果没有类型限制,所有与 IO 相关的内容都会很危险。所以我们会完全禁止 IO。没什么用。
在类型系统的帮助下,相反,我们可以导出一些 "dangerous" IO 操作,知道它们只能在 "controlled" 个地方执行,这些地方必须带有 IO
标签在他们的类型中。让他们不再危险。
因此,纯度来自静态保证和谨慎导出的结合。
人们总是说 Haskell 的类型系统可以防止不纯代码污染纯代码,因为您总是必须在类型签名中指定 IO
。但是,这是类型系统本身的结果,还是真的只是 IO(..)
没有导出?
基本上,如果类型构造函数可用,是否可以完成类似的事情?
ioToPure :: IO a -> a
ioToPure (IO ioValue) = ioValue
是的,这在某种意义上是正确的。
类型系统本身对 IO
一无所知,也不需要。不同的语言特性向用户隐藏了 IO 操作的真实表示,因此不可能 "just run" IO 操作。
所以,事实是,Haskell 和类似语言的 IO 安全性是多种语言特性和属性的综合结果,最突出的是:
- 不接受用户 "shut up, I know better" 的强类型系统。
- 一切都是打出来的属性。我在这里的意思是,在不纯的语言中,你有 "statements" 并且即使类型系统很强大,它也不会超过下一个分号。而在 Haskell 中,我们只有表达式,每个表达式的每一位都有一个类型,并最终影响表达式所在函数的类型。
- 隐藏类型表示的语言特性。
尽管如此,我认为表达式 "the type system makes sure that impure and pure code is separated" 是一种无害的简化。
当然,导出低级基元可能会在任何地方产生副作用。 而且,是的,你可以通过避免出口每一种危险的东西来获得纯度仅。不需要类型级机器。
但是,如果没有类型限制,所有与 IO 相关的内容都会很危险。所以我们会完全禁止 IO。没什么用。
在类型系统的帮助下,相反,我们可以导出一些 "dangerous" IO 操作,知道它们只能在 "controlled" 个地方执行,这些地方必须带有 IO
标签在他们的类型中。让他们不再危险。
因此,纯度来自静态保证和谨慎导出的结合。