Monads'红色管'与类型不同?

时间:2013-02-25 13:57:05

标签: haskell monads

关于monad,'pipe'和'红色管',我是reading an interesting article。从它看起来它是说功能参数或类是管道的类型,以确保一切都适合。然后它成为一个红色的管道,必须始终是一个红色的管道和纯度。这部分我不明白

为什么“红色管道”不能成为“蓝色管道”?红色管道可以转换成普通管道吗?这与纯度有什么关系?我能想到这就像class RedPipe: PlainPipe { /* same interface and implementation here*/ }吗?

2 个答案:

答案 0 :(得分:5)

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

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

f :: Int -> Int

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

如果我有类型的功能:

g :: Double -> State Int Double

...该函数将Double作为参数并生成一种生成Double的方法,但前提是我允许它查阅或修改某些Int状态。 / p>

如果我有类型的功能:

h :: Int -> Maybe String

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

如果我有类型的功能:

i :: String -> IO ()

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

这意味着我们可以查看函数或值的类型,并立即了解它们使用的功能。所以,例如,如果我在类型中看到Maybe,我知道有可能失败,如果我没有,那么我知道没有可能失败。同样,如果我在类型中看到IO,那么我知道可能存在副作用,但如果我在类型中看不到IO,那么就没有副作用的可能性。< / p>

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

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

答案 1 :(得分:3)

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

square :: Double -> Double

此类签名告诉我

  1. 函数square没有任何副作用。它不会偷偷摸摸地更新数据库,或者在屏幕上打印某些内容,或者更改某些状态数据,或者让我感到惊讶。 (例如,在Java或C中,我必须阅读函数及其调用的任何函数,或者依赖文档来了解函数的功能。)

  2. 每当我使用特定值(例如square 5)调用它时,我将得到完全相同的结果。这称为参照透明度,它允许编译器进行一些优化,因为它知道这个值永远不会改变,所以它只需要计算一次。