Haskell中的安全应用程序

5
我有一段代码,在列表单子中应用了一个函数。该函数的参数可能存在非穷尽模式匹配。因此,当应用该函数时,可能会出现“非穷尽模式匹配”错误。我想将此错误转换为单子失败(在本例中是空列表)。换句话说,我希望获得与 do 块中的 Some Pattern Here <- some value 失败时发生的类似行为。
问题:是否有一种有效的方法使函数应用安全?通过有效,我指的是类似于使应用函数穷尽匹配并显式失败的方法。

问题不够清晰。既然你在列表单子里,为什么不在do结构中进行模式匹配或者使用显式的case结构呢?最好附上一段示例代码。 - is7s
2个回答

3

一种选择是使用spoon将函数从抛出异常的函数转换为返回Maybe a值的函数。然后,只需将Nothing转换为[]即可。


4
我不确定是否应该积极推广Spoon函数,可以参考这个帖子:http://www.reddit.com/r/haskell/comments/acasn/tired_of_functions_that_could_live_in_maybe_but/ - stephen tetley
我可能不会冒险使用它。无论如何,我相信这是最接近我所要求的。 - julx
2
我认为Spoon很好。是的,它会破坏理论属性等等,但该库的目的是处理糟糕的代码(这些代码本来就没有以与所述理论属性相协调的方式定义)。当替代方案是从头开始重新实现(或在这种情况下...解析和修复用户的代码--呕吐!)时,Spoon是一个很好的选择。 - luqui

2

嗯,也许有一个注意事项? 但是你需要在IO单子中工作:

import Prelude hiding (catch)
import Control.Monad (MonadPlus, mzero)
import Control.Exception (catch, SomeException)

data B = T | F
    deriving (Show)

f :: B -> B
f T = F

justCatch :: (MonadPlus m) => a -> IO (m a)
justCatch x = catch (x `seq` (return . return) x) handler
  where
    handler :: (MonadPlus m) => SomeException -> IO (m a)
    handler _ = return mzero

我不确定这个解决方案可能存在的问题。乍一看似乎可以工作,但我也想听听有经验的Haskeller的意见。

在我的代码中,我肯定不会使用这个解决方案:错误应该被视为错误,而不是隐藏它。

*Main> justCatch $ f T :: IO [B]
[F]
*Main> justCatch $ f F :: IO [B]
[]
*Main> justCatch $ f F :: IO (Maybe B)
Nothing
*Main> justCatch $ f T :: IO (Maybe B)
Just F
*Main> f T
F
*Main> f F
*** Exception: except.hs:8:1-7: Non-exhaustive patterns in function Main.f

IO单子不是一个选项。我尽可能地保持我的代码纯粹。 - julx
2
据我所知,你只能使用catch来处理像那样的异常(这会强制你在IO中工作)。如果你不想使用Daniel提出的使用不安全操作的sppon,恐怕你可能没有其他选择。 - Riccardo T.
好的,否定的答案仍然是一个答案。谢谢。 - julx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接