纯代码和不纯的代码? I / O数据类型相关

时间:2015-10-10 17:48:50

标签: haskell functional-programming

name <- getLine

以下段落是关于该线如何工作的。有人可以向我解释这意味着什么吗?提前谢谢。

  

getLine在某种意义上是不纯的,因为它的结果值不是   保证两次执行时相同。这就是它排序的原因   受IO类型构造函数污染,我们只能获取该数据   在I / O代码中。而且因为I / O代码也受到污染,任何计算   这取决于受污染的I / O数据会产生污点。

     

当我说污点时,我并不是说我们能够以这种方式受到污染   永远不要再使用I / O动作中包含的结果了   码。不,我们暂时取消了I / O操作中的数据   我们将它绑定到一个名称。当我们命名&lt; - getLine时,name就是一个   普通字符串,因为它表示框内的内容。

1 个答案:

答案 0 :(得分:2)

该段暗示您不能在具有&#34;纯&#34;的函数中使用getLine这一事实。类型,没有IO monad。例如。如果我们试图运行

lineLength :: Int -> Int
lineLength n = n + length getLine

编译器会抱怨,因为length需要String(或任何其他列表类型),但getLineIO String。因此存在类型不匹配。

但这并不意味着lengthgetLine无法合成:这里是如何

lineLength :: Int -> IO Int
lineLength n = do
    line <- getLine
    return (n + length line)

上面我们暂时&#34;删除IO&#34;自line :: String开始,以便length可以应用于n,并return添加到结果中。但是,我们被迫使用Int将纯IO Int结果转换为IO

注意IO如何在函数签名中结束:这是不可避免的。 在Haskell中,如果函数确实存在诸如使用IO之类的内容,那么类型系统会强制您在类型中使用IO。这是&#34;污点&#34;引用是指:一旦你使用IO类型的不纯函数/值,你必须在你自己的代码类型中使用IO,并且任何调用者依次会有使用f :: Int -> Int。必须在类型签名中传播杂质。

这也意味着如果你看到body{ ---other existing attributes--- overflow-y: scroll; } ,你可以依赖一个事实,即编译器证明函数是纯的:它将为同一个输入返回相同的结果。 (有一些低级方法可以避免这种情况,但它们并不适用于常规代码。)