# Scala style andThen

Hello,

Is the following code optimal in sense of Scala idiomatic style? Is it ok that “case None” appears first? Is it possible to rewrite the logic using “andThen” operator?

``````  def isStraightFlush(cards: CardList): Option[Rank] = {
isStraight(cards) match {
case None => None
case _ => isFlush(cards) match {
case None => None
case _ => Some(Rank(Rank.STRAIGHT_FLUSH, cards, cards))
}
}
}

``````

Thank you.

``````def isStraightFlush(cards: CardList): Option[Rank] = for {
_ <- isStraight(cards)
_ <- isFlush(cards)
} yield Rank(Rank.STRAIGHT_FLUSH, cards, cards)
``````

Seems a lot simpler

2 Likes

It seems `isStrait` and `isFlush` could both return `Boolean`.

``````if (isStraight(cards) && isFlush(cards))
Some(Rank(Rank.STRAIGHT_FLUSH, cards, cards))
else
None
``````

Or you could turn `Option` into `Boolean`

``````if (isStraight(cards).isDefined && isFlush(cards).isDefined)
Some(Rank(Rank.STRAIGHT_FLUSH, cards, cards))
else
None
``````

Option as a sequence. This is the perfect solution! Thank you!

That’s not really “option as a sequence” - `Option` has its own “native” notion of `#map`/`#flatMap()`.

1 Like

Hello,

• Having the None case first looks fine

• Method names that start with “is” are usually used for methods that return Boolean

• The logic looks incorrect to me: if we see “flush” simply as a synonym for “all cards of the same suit” and “straight” as a synonym for “cards form a sequence”, then we could say that “straight flush” is the intersection of “flush” and “straight”. However, when we start talking about ranks, that is not really true: “straight flush”, “flush” and “straight” are three different ranks that do not intersect, so it is incorrect to say that the rank “straight flush” is the intersection of the rank “flush” and the rank “straight”.

Thank you for the note about prefix “is”. I’ve renamed these methods to probe* .
I’m sure the logic is correct. The “straight flush” is combination of “straight” + “flush”. Yes, they are three different ranks. My code for rank evaluation from 5 cards set looks like:

``````def evalCards(funcs: List[CardList => Option[Rank]], cards: CardList): Option[Rank] = {
funcs match {
case List() => None
case hd :: tail => hd(cards) match {
case None => evalCards(tail, cards)
case x => x
}
}
}

val allCombs: List[CardList => Option[Rank]] = List(
probeStraightFlush,
probeFourOfKind,
probeFullHouse,
probeFlush,
probeStraight,
probeThreeOfKind,
probeTwoPairs,
probePair,
probeHighCard)

evalCards(allCombs, cards)

``````