user2066049
user2066049

Reputation: 1371

Side effecting function returning disjunction

I have a side effecting function which mutates class variable or Throw an exception if precondition isn't met. After adding into class level mutable Map I want to return a "boolean" from the function indicating a success. So below is what I am thinking about but hard-coding boolean to "true" feels inappropriate however that would be the case when it goes into yield block as otherwise left side of disjunction will be populated with an exception.

def add(e: Entity, value: String): \/[Throwable,Boolean] = {
checkIfFieldIsKey(e.id) match {
  case Some(id) =>
    val validId = validateIdType(..)
    for {
      k <- validId
    } yield { keys += (e -> k); true }
  case None =>
    for {
      r <- validateTypeAndValue(e, value)
    } yield { values += (e -> value); true } 
  }
}

where 'keys' and 'values' are 'val' instances of ConcurrentHashMap. So every time 'add' is successful right side of disjunction will always be "true" meaning boolean value will never be false. does this look appropriate?

Upvotes: 2

Views: 127

Answers (2)

Travis Brown
Travis Brown

Reputation: 139038

When a side-effecting method has no meaningful return value, you typically return Unit. If you want to capture the possibility of failure, it's perfectly reasonable to return Throwable \/ Unit, which is probably what I'd do here. In any case I'd say your intuition that it's a bad idea to return a Throwable \/ Boolean where the right side can never be anything but true is spot on.

Upvotes: 2

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297185

It seems silly. It could be reduced to Option[Throwable] -- None if successful, or the exception if it wasn't. The only thing against it is that None isn't usually associated with success.

As an alternative, write your own maybe monad, with Success and Failure(throwable) as it's cases.

Upvotes: 1

Related Questions