本文介绍了如何收集Either Monad中的所有错误消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 Applicatives Either Monad 验证 Record 的构造.它工作正常.但是我看不到所有错误消息.只有第一个可见,因为任一Monad Right 路径都会忽略它们.

I tried to validate the construction of a Record with Applicatives and the Either Monad. It works fine. But I can't see all Error Messages. Only the first is visible because the Right Path of the Either Monad ignores them.

这是我的代码:

import Data.Either (either)
import Text.Printf (printf)

data Record = Record
  { fieldA :: String
  , fieldB :: String
  , fieldC :: String
  } deriving (Show, Eq)

type Err = String
    
setField :: String -> String -> Either Err String
setField field value
  | length value > 0 = Right value
  | otherwise = Left $ printf "value for field %s is to short" field

setFieldA :: String -> Either Err String
setFieldA = setField "fieldA"

setFieldB :: String -> Either Err String
setFieldB = setField "fieldB"

setFieldC :: String -> Either Err String
setFieldC = setField "fieldC"
  
makeRecord :: Either Err Record
makeRecord = Record
  <$> setField "fieldA" "valueA"
  <*> setField "fieldB" "valueB"
  <*> setField "fieldC" "valueC"

makeRecord' :: Either Err Record
makeRecord' = Record
  <$> setFieldA "valueA"
  <*> setFieldB "valueB"
  <*> setFieldC "valueC"

recordFromEither :: Either Err Record -> Maybe Record
recordFromEither r =
  case r of
    Right v -> Just $ v
    Left _ -> Nothing

main :: IO ()
main = putStrLn $ output
  where
    output = case makeRecord of
      Right v -> show v
      Left err -> show err

main' :: IO ()
main' = putStrLn $ either id show makeRecord'

我的问题是如何保留和显示所有错误消息.也许和州立莫纳德一起?

My question is how can I keep and display all error messages. Maybe with the State Monad?

推荐答案

这是因为 Ething Applicative 实例的工作方式.您可以做的是将 Ething 换成 newtype :

That's because of the way the Either Applicative instance works. What you can do is to wrap Either in a 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 结果.有关更多详细信息,请参阅我在应用验证上的文章.

You can now use <$> and <*> to compose a Validation [Err] Record result. See my article on Applicative validation for more details.

这篇关于如何收集Either Monad中的所有错误消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 12:28