如何解决如何收集Either Monad中的所有错误消息?
我试图用Record
和Applicatives
验证Either Monad
的构造。它工作正常。但是我看不到所有错误消息。由于Right
的{{1}}路径会忽略它们,因此只有第一个可见。
这是我的代码:
Either Monad
我的问题是如何保留和显示所有错误消息。也许和州立单子党在一起?
解决方法
要累积错误,Applicative
需要一个不同的Either
实例。 Either
的这种变体有时称为Validation
。关于该实例,至少有两个关于Hackage的库提供了Either
的变体:
-- Standard definition
(<*>) :: Either e (a -> b) -> Either e a -> Either e b
Left e <*> _ = Left e
Right _ <*> Left e = Left e
Right f <*> Right x = Right (f x)
-- "Validation" variant
(<*>) :: Monoid e => Either e (a -> b) -> Either e a -> Either e b
Left e <*> Left e' = Left (e <> e')
Left e <*> Right _ = Left e
Right _ <*> Left e = Left e
Right f <*> Right x = Right (f x)
在这个主题上,一个共同的争论点是“ validation”变体是否与Monad
的{{1}}操作兼容(或者首先是否应该兼容):>
Either
我在上面提到了两个库,因为对此主题有不同的看法(我认为这归结为对传统的平等定义没有达成共识,这本身就是Haskell没有形式语义的症状)。
- validation 库说不存在兼容的monad实例,因此避免定义一个实例。
- monad-validate 库认为上述法律符合特定的对等概念,在错误报告的情况下可以做的很好,在这种情况下,应该发生的最坏情况是您报告的错误可能比预期的要少。 (图书馆的文档也包含很多相关的说明。)
这是因为Either
Applicative
实例的工作方式。您可以做的就是将Either
包裹在newtype
中:
newtype Validation e r = Validation (Either e r) deriving (Eq,Show,Functor)
然后给它另一个Applicative
实例:
instance Monoid m => Applicative (Validation m) where
pure = Validation . pure
Validation (Left x) <*> Validation (Left y) = Validation (Left (mappend x y))
Validation f <*> Validation r = Validation (f <*> r)
您现在可以使用<$>
和<*>
来组成Validation [Err] Record
的结果。有关更多详细信息,请参见我在Applicative validation上的文章。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。