到目前為止,我已經看到了許多可能導致 ⊥ 的部分函式的“可能”版本,例如readMaybeforread和listToMaybefor head; 有時我想知道我們是否可以概括這個想法并制定出這樣一個函式safe :: (a -> b) -> (a -> Maybe b),將任何部分函式轉換為更安全的總替代方案,該替代方案Nothing在原始函式中呼叫錯誤堆疊的任何實體上回傳。到目前為止,我還沒有找到一種方法來實作這樣的safe功能或類似的現有實作,我開始懷疑這個想法是否真的可行。
uj5u.com熱心網友回復:
實際上有兩種底,非終止和錯誤。由于顯而易見的原因,您無法捕獲非終止,但您可以捕獲錯誤。這是一個快速拼湊的版本(我不是專家,所以可能有更好的方法)
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Exception
import System.IO.Unsafe
safe f = unsafePerformIO $ do
z <- try (evaluate f)
let r = case z of
Left (e::SomeException) -> Nothing
Right k -> Just k
return r
這里有些例子
*Main > safe (head [42])
Just 42
*Main > safe (head [])
Nothing
*Main λ safe (1 `div` 0)
Nothing
*Main λ safe (1 `div` 2)
Just 0
uj5u.com熱心網友回復:
不,這是不可能的。它違反了一個稱為“單調性”的屬性,該屬性表示一個值在處理時不能變得更加明確。你不能在底部分支 - 嘗試處理一個總是會導致底部。
或者至少,這對于 Haskell 評估所基于的領域理論都是正確的。但是 Haskell 有一些領域理論沒有的額外功能......就像執行IO動作與評估不同,并且unsafePerformIO讓您將執行隱藏在評估中。勺子庫將所有這些想法打包在一起并且可以完成。這并不完美。它有漏洞,因為這不是你應該能夠做的事情。但它在許多常見情況下都能發揮作用。
uj5u.com熱心網友回復:
考慮函式
collatz :: Integer -> ()
collatz 1 = ()
collatz n
| even n = collatz $ n`div`2
| otherwise = collatz $ 3*n 1
(為簡單起見,我們假設Integer是正整數的型別)
這是一個全功能嗎?沒人知道!據我們所知,它可能是全部的,所以你提議的safe-guard 永遠不會屈服Nothing。但是也沒有人找到證明它是全部的證據,所以如果safe只是總是回饋,Just (collatz n)那么這可能仍然只是部分的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/517127.html
標籤:哈斯克尔偏函数
上一篇:Coq型別類方法的默認實作
