簡體   English   中英

溶解多個 arguments 的更好方法

[英]better way to dissolve multiple Either arguments

我有一個 model,看起來像這樣:

case class ItemEntity private(
    userId: IdValue,
    title: TitleValue,
    description: DescriptionValue,
    media: MediaValue,
    price: MoneyValue,
    stock: StockValue
)

在這個 model 的配套 object 中,是一個構造函數,目前看起來像這樣:

object ItemEntity
{
    def fromUnsafe(
        mayBeUserId: Either[IdError, IdValue],
        mayBeTitle: Either[TitleError, TitleValue],
        mayBeDescription: Either[DescriptionError, DescriptionValue],
        mayBeMedia: Either[MediaError, MediaValue],
        mayBePrice: Either[MoneyError, MoneyValue],
        mayBeStock: Either[StockError, StockValue]
    ): Either[ItemError, ItemEntity] =
    {
        mayBeUserId match
            case Right(id) => mayBeTitle match
                case Right(title) => mayBeDescription match
                    case Right(description) => mayBeMedia match
                        case Right(media) => mayBePrice match
                            case Right(price) => mayBeStock match
                                case Right(stock) => Right(
                                    ItemEntity(
                                        userId = id,
                                        title = title,
                                        description = description,
                                        media = media,
                                        price = price,
                                        stock = stock
                                    )
                                )
                                case Left(stockError) => Left(ItemError.Error(stockError))
                            case Left(priceError) => Left(ItemError.Error(priceError))
                        case Left(mediaError) => Left(ItemError.Error(mediaError))
                    case Left(descriptionError) => Left(ItemError.Error(descriptionError))
                case Left(titleError) => Left(ItemError.Error(titleError))
            case Left(idError) => Left(ItemError.Error(idError))
    }
}

如您所見,代碼有很多樣板。

但我想不出更好的方法來編寫這個構造函數......

所以我的問題是:

有沒有更好的方法來寫這個?

您可以使用理解,但首先您必須 map 或將左值擴大到相同類型:

def fromUnsafe(
                mayBeUserId: Either[IdError, IdValue],
                mayBeTitle: Either[TitleError, TitleValue],
                mayBeDescription: Either[DescriptionError, DescriptionValue],
                mayBeMedia: Either[MediaError, MediaValue],
                mayBePrice: Either[MoneyError, MoneyValue],
                mayBeStock: Either[StockError, StockValue]
              ): Either[ItemError, ItemEntity] =
  for {
    id <- mayBeUserId.left.map(ItemError.Error)
    title <- mayBeTitle.left.map(ItemError.Error)
    description <- mayBeDescription.left.map(ItemError.Error)
    media <- mayBeMedia.left.map(ItemError.Error)
    price <- mayBePrice.left.map(ItemError.Error)
    stock <- mayBeStock.left.map(ItemError.Error)
  } yield ItemEntity(id, title, description, media, price, stock)

如果錯誤類型可以擴大到相同的類型那么你也可以在理解后將left.map

  (for {
    id <- mayBeUserId
    title <- mayBeTitle
    description <- mayBeDescription
    media <- mayBeMedia
    price <- mayBePrice
    stock <- mayBeStock
  } yield ItemEntity(id, title, description, media, price, stock)).left.map(ItemError.Error)

您還可以將left.map替換為leftMap和/或leftWiden為 Cats。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM