[scala] 다음과 유사한 삼항 연산자? :

다음과 같은 구문을 피하려고합니다.

val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result

좋습니다.이 예에서 thenelse분기는 단순하지만 복잡한 것을 이미지화 할 수 있습니다. 다음을 구축했습니다.

object TernaryOp {
  class Ternary[T](t: T) {
    def is[R](bte: BranchThenElse[T,R]) = if (bte.branch(t)) bte.then(t) else bte.elze(t)
  }
  class Branch[T](branch: T => Boolean) {
    def ?[R] (then: T => R) = new BranchThen(branch,then)
  }
  class BranchThen[T,R](val branch: T => Boolean, val then: T => R)
  class Elze[T,R](elze: T => R) {
    def :: (bt: BranchThen[T,R]) = new BranchThenElse(bt.branch,bt.then,elze)
  }
  class BranchThenElse[T,R](val branch: T => Boolean, val then: T => R, val elze: T => R)
  implicit def any2Ternary[T](t: T) = new Ternary(t)
  implicit def fct2Branch[T](branch: T => Boolean) = new Branch(branch)
  implicit def fct2Elze[T,R](elze: T => R) = new Elze(elze)
}

위의 간단한 예를 다음으로 대체 할 수 있다고 정의했습니다.

this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}

하지만 어떻게 제거 할 수 s: String =>있습니까? 나는 다음과 같은 것을 원한다.

this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}

컴파일러는 유형을 추론하기 위해 추가 항목이 필요하다고 생각합니다.



답변

스칼라에서 선두 토큰을 보존하는 삼항 연산자를 정의하는 방법을 결합 할 수 있습니다 . 에 대한 대답으로 값이 좋은 패턴을 배치됩니다 옵션?얻기 위해

scala>   "Hi".getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res0: String = String

scala> List.getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res1: String = List

이것이 귀하의 필요에 적합합니까?


답변

에서 토니 모리스 ‘람다 블로그 :

이 질문을 많이 듣습니다. 네 그렇습니다. 대신에 c ? p : q기록 if(c) p else q됩니다.

이것은 바람직하지 않을 수 있습니다. 아마도 Java와 동일한 구문을 사용하여 작성하고 싶을 것입니다. 슬프게도 할 수 없습니다. 이것은 :유효한 식별자 가 아니기 때문 입니다. 두려워하지 마십시오 |! 이것에 만족 하시겠습니까?

c ? p | q

그런 다음 다음 코드가 필요합니다. =>인수에 대한 call-by-name ( ) 주석을 확인하십시오. 이 평가 전략은 Java의 삼항 연산자를 올바르게 다시 작성하는 데 필요합니다. 이것은 Java 자체에서는 수행 할 수 없습니다.

case class Bool(b: Boolean) {
  def ?[X](t: => X) = new {
    def |(f: => X) = if(b) t else f
  }
}

object Bool {
  implicit def BooleanBool(b: Boolean) = Bool(b)
}

다음은 방금 정의한 new 연산자를 사용한 예입니다.

object T {   val condition = true

  import Bool._

  // yay!   
  val x = condition ? "yes" | "no"
}

재미있게 보내세요;)


답변

기본 Scala로 표현 된 Rex Kerr의 답변 :

"Hi".getClass.getSimpleName match {
  case x if x.endsWith("$") => x.init
  case x => x
}

if-else 구조의 어떤 부분을 최적화하고 싶은지 잘 모르겠지만.


답변

Scala의 if-else 구조는 값을 반환하므로 이것을 사용할 수 있습니다.

val a = if (1 < 0) 1 else 2

추가 정보 : https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples


답변

왜냐하면 : 항상 백틱으로 이스케이프하지 않는 한 그 자체로는 유효한 연산자가 아닙니다. :“|”와 같은 다른 문자를 사용할 수 있습니다. 위의 답변 중 하나와 같습니다. 하지만 수염을 가진 엘비스는 어떻습니까? ::

implicit class Question[T](predicate: => Boolean) {
  def ?(left: => T) = predicate -> left
}
implicit class Colon[R](right: => R) {
  def ::[L <% R](pair: (Boolean, L)): R = if (q._1) q._2 else right
}
val x = (5 % 2 == 0) ? 5 :: 4.5

물론 값이 목록이면 :: 연산자가 있기 때문에 다시 작동하지 않습니다.


답변