在Haskell中,任何部分函数都可以转换为完整版本吗



到目前为止,我已经看到了许多"也许"某些可能导致Γ的偏函数的版本,如readreadMaybeheadlistToMaybe;有时我想知道我们是否可以推广这个想法,并计算出这样一个函数safe :: (a -> b) -> (a -> Maybe b),将任何部分函数转换为它们更安全的总替换函数,在原始函数中调用错误堆栈的任何实例上返回Nothing。到目前为止,我还没有找到一种方法来实现这样的safe函数或现有的类似实现,我开始怀疑这个想法是否真的可行。

底部实际上有两种,非终止和错误。由于显而易见的原因,您无法捕获非终止,但您可以捕获错误。这是一个快速组合的版本(我不是专家,所以可能有更好的方法(

{-# 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

不,这是不可能的。它违反了名为";单调性";,它说,一个值在处理过程中不能变得更明确。你不能在底部分支——试图处理一个值总是会导致底部。

或者至少,Haskell评估所基于的领域理论都是如此。但Haskell有一些额外的特征,领域理论没有。。。就像执行IO操作与求值不同,unsafePerformIO让您在求值中隐藏执行一样。勺子库将所有这些想法打包在一起,尽可能做到。这并不完美。它有漏洞,因为这不是你应该能做到的。但它在很多常见情况下都能做到。

考虑函数

collatz :: Integer -> ()
collatz 1 = ()
collatz n
| even n     = collatz $ n`div`2
| otherwise  = collatz $ 3*n + 1

(为了简单起见,假设Integer是正整数的类型(

这是一个完整的函数吗?没人知道!据我们所知,它可能是总和,所以你提出的safe-保护永远不会产生Nothing。但也没有人找到它是完全的证据,所以如果safe总是返回Just (collatz n),那么这可能仍然只是部分的。

相关内容

  • 没有找到相关文章

最新更新