1

我正在阅读一篇关于 monad、“管道”和成为“红色管道”的有趣文章。从表面上看,函数参数或类是确保一切都适合的管道类型。然后它会成为一个红色的管道,并且必须始终是一个红色的管道和纯度。这部分没看懂

为什么“红管”不能变成“蓝管”?可以将红色管道转换为普通管道吗?这和纯洁有什么关系?我可以认为这是类似的class RedPipe: PlainPipe { /* same interface and implementation here*/ }吗?

4

2 回答 2

5

在 Haskell 中,函数的类型准确地告诉你它做了什么,更重要的是,它不做什么。这使得推理 Haskell 代码更容易。

例如,如果我有以下类型的函数:

f :: Int -> Int

我知道它需要一个Int作为输入并产生一个Int作为输出,它什么也不做。重要的是,我知道它没有副作用。

如果我有一个类型的功能:

g :: Double -> State Int Double

...该函数将 aDouble作为参数并产生一种产生 a 的方法Double,但前提是我允许它咨询或修改某些Int状态。

如果我有一个类型的功能:

h :: Int -> Maybe String

我知道这个函数需要 aInt并且可能会产生 a String,或者它可能会失败,什么也不产生。请注意,前两个函数都没有返回Maybe,这意味着它们不会失败。Haskell 默认不允许失败(即可以为空的值)。

如果我有一个类型的功能:

i :: String -> IO ()

我知道这个函数需要一个String并且可以运行来产生副作用。请注意,以前的函数都没有IO在它们的类型中,这意味着它们不会产生副作用。Haskell 默认不允许副作用。您必须在类型中明确选择加入它们。

这意味着我们可以查看函数或值的类型,并立即了解它们正在使用哪些特性。因此,例如,如果我Maybe在类型中看到 a,我知道有可能失败,如果没有,那么我知道没有失败的可能性。同样,如果我IO在类型中看到 an,那么我知道可能会产生副作用,但如果我IO在类型中看到 no,那么就不会产生副作用。

在主流语言中,您没有这种选择性地“选择加入”功能的能力。默认情况下,所有功能始终处于启用状态,这意味着您必须始终检查,null因为您无法保证某些功能没有失败,并且您必须始终运行测试,因为您无法保证某些功能没有失败不要隐式修改系统的状态。

Haskell 允许您限制函数的行为,以便您对它们的“权限”进行更细粒度的控制,这使得更容易扩展到没有错误的大型程序,也更容易阅读和理解 Haskell 代码,因为该类型枚举了全部范围代码的行为,因此您永远不必了解超出类型允许的内容。

于 2013-02-25T14:26:51.370 回答
3

作者使用术语“红管”和“蓝管”作为比喻。据我所知,这不是广泛使用的术语。我认为他文章的重点是,Java 等语言提供的类型安全有助于捕捉某些类型的程序员错误,将函数与不纯函数隔离可以捕捉更多。使用他的一个例子:

square :: Double -> Double

这个类型签名告诉我

  1. 该功能square没有任何副作用。它不会偷偷溜走并更新数据库,或者在屏幕上打印一些东西,或者改变一些状态数据,或者以其他方式让我感到惊讶。(例如,在 Java 或 C 中,我必须阅读函数及其调用的任何函数,或者依赖文档来了解函数的作用。)

  2. 每次我用一个特定的值调用它,比如说,square 5我都会得到完全相同的结果。这称为引用透明性,它允许编译器做一些优化,因为它知道这个值永远不会改变,所以只需要计算一次。

于 2013-02-25T14:18:17.567 回答