如何启用应用验证以返回MonadThrow?

问题描述 投票:1回答:1

在我看来,在Haskell中验证输入数据的惯用方式是通过应用链:

mkMyData :: a -> b -> c -> Maybe MyData
mkMyData x y z =
    MyData
        <$> validateA x
        <*> validateB y
        <*> validateC z

其中验证函数本身返回Maybe值。为了使我的智能构造函数mkMyData更灵活,我希望它返回MonadThrow。也就是说,

mkMyData :: MonadThrow m => a -> b -> c -> m MyData

这是否需要每个验证函数返回MonadThrow而不是Maybe?还是有某种方法可以将每个验证的特定Maybe结果转换为更通用的MonadThrow,而不会破坏应用结构并大大简化代码?

或者也许换个说法?是否有必要在基本库函数中争取更通用的MonadThrow返回类型,而以更复杂,更惯用的代码为代价?

validation haskell error-handling monads applicative
1个回答
2
投票
答案与your last question相同。您为新的验证功能建议的类型,

mkMyData :: MonadThrow m => a -> b -> c -> m MyData

表示它完全可以在任何monad中工作,只要该monad有扔东西的方式。如果该函数的实现依赖于能够显式返回NothingJust结果,则它将不满足该条件。

相反,您必须重写当前返回Maybe a的函数以改为依赖MonadThrow。例如,代替

validateA :: a -> Maybe t validateA x | acceptable x = Just $ convert x | otherwise = Nothing

您将需要写

validateA :: MonadThrow m => a -> m t validateA x | acceptable x = pure $ convert x | otherwise = throwM $ problemWith x

(其中所有以x作为参数的函数都已组成,需要以某种方式与您的域相关联。    
© www.soinside.com 2019 - 2024. All rights reserved.