2012-12-07 32 views
10

由於shown in this answerseq結合undefined在等式推理方面做了很奇怪的事情,例如它可以使任何monad失敗。另一個例子是this question與`seq`相比``評估'安全嗎?

最近我偶然發現了evaluate :: a -> IO a做了類似的事情 - 它評估它的參數到WHNF,但只有當IO行動被評估。這似乎更安全了,因爲人們期望「在IO我們可以做所有事情」。當然,它無法在任何地方使用,但通常需要評估一個表達式與某種操作相關(例如,在使用MVar s時,強制生成的線程評估計算而不是消耗線程)。

所以我想問一下,evaluate有多安全?是否有可能創建示例(當然涉及IO),它破壞了有關像seq這樣的代碼的推理?或者我可以將其視爲安全替代seq(如果某個特定程序可能)?

回答

5

不,您仍然遇到seq命令導致的相同問題,因爲在第一個參數evaluate中使用的任何monad將會破壞其monad規則。立足其拖離規則ertes的回答是:

在Kleisli類的單子引起return是 身份態射和(<=<)是組成。所以return必須是 身份(<=<)

return <=< x = x 

這意味着你應該能夠使用任何有效的單子與x更換return <=< x不改變程序的運行。

使用與evaluate功能...

evaluate (return <=< undefined :: a -> Identity b) >> putStrLn "hello" 

輸出打招呼。使用什麼應該由undefined更換return <=< undefined是等效的語句:

evaluate (undefined :: a -> Identity b) >> putStrLn "hello" 

,而不是導致Prelude.undefined例外。

這隻發生在評估函數中。請注意0​​與evaluate具有完全相同的類型簽名。如果在上述命令中將evaluate替換爲return,則兩個命令的結果操作相同(它們輸出hello)。