[SCALA] 엉성한 부산물 패턴 매칭
SCALA엉성한 부산물 패턴 매칭
나는 볼품의 로서도와 패턴 매칭을 사용할 수 있습니까?
import shapeless.{CNil, :+:}
type ListOrString = List[Int] :+: String :+: CNil
def f(a: ListOrString): Int = a match {
case 0 :: second :: Nil => second
case first :: Nil => first
case Nil => -1
case string: String => string.toInt
}
그 과정은이 부산물 (Coproduct)으로 박스되기 때문에,하지 작업을 수행합니다.의
패턴 일치 할 수있는 능력을 로서도을 사용하고 유지하는 다른 방법이 있습니까?
해결법
-
==============================
1.당신은 패턴 일치의 INL 및 INR 생성자를 사용할 수 있습니다 :
당신은 패턴 일치의 INL 및 INR 생성자를 사용할 수 있습니다 :
import shapeless.{ CNil, Inl, Inr, :+: } type ListOrString = List[Int] :+: String :+: CNil def f(a: ListOrString): Int = a match { case Inl(0 :: second :: Nil) => second case Inl(first :: Nil) => first case Inl(Nil) => -1 case Inr(Inl(string)) => string.toInt }
당신이 컴파일러가 일치 철저한-우리는 그런 경우가 일치하는 것이 불가능 것을 알고 있지만, 컴파일러하지 않는 것을 말할 수있을하려는 경우 CNIL의 경우를 처리하기 때문에이 방법은 너무, 적합하지 않습니다 우리는 이런 일을 할 필요가 :
def f(a: ListOrString): Int = a match { case Inl(0 :: second :: Nil) => second case Inl(first :: Nil) => first case Inl(Nil) => -1 case Inl(other) => other.sum case Inr(Inl(string)) => string.toInt case Inr(Inr(_)) => sys.error("Impossible") }
또한 개인적으로 단지 INR과 INL 조금 직관적와 부산물의 해당 위치로 이동 찾을 수 있습니다.
일반적으로이 다형성 함수 값과 부산물을 통해 배하는 것이 좋습니다 :
object losToInt extends shapeless.Poly1 { implicit val atList: Case.Aux[List[Int], Int] = at { case 0 :: second :: Nil => second case first :: Nil => first case Nil => -1 case other => other.sum } implicit val atString: Case.Aux[String, Int] = at(_.toInt) } def f(a: ListOrString): Int = a.fold(losToInt)
이제 컴파일러는 당신이 불가능한 경우를 처리하지 않고 exhaustivity을 확인합니다.
-
==============================
2.난 그냥 당신의 필요를 위해 잘 작동 할 수 있음을 여기에 볼품에게 끌어 오기 요청을 제출했다. (그냥 끌어 오기 요청하고 수정을 거칠 수있다 또는 거부 ...하지만 기계를 가지고 당신이 유용한 경우 자신의 코드에서 자유롭게 사용합니다.)
난 그냥 당신의 필요를 위해 잘 작동 할 수 있음을 여기에 볼품에게 끌어 오기 요청을 제출했다. (그냥 끌어 오기 요청하고 수정을 거칠 수있다 또는 거부 ...하지만 기계를 가지고 당신이 유용한 경우 자신의 코드에서 자유롭게 사용합니다.)
로부터 커밋 메시지 :
val result = c.foldCases[Double] .atCase(i => math.sqrt(i)) .atCase(s => s.length.toDouble) .atCase(b => if (b) 100.0 else -1.0)
귀하의 예를 들어, 당신이 할 수 있습니다 :
def f(a: ListOrString): Int = a.foldCases[Int] .atCase(list => list match { case 0 :: second :: Nil => second case first :: Nil => first case Nil => -1 case other => other.sum }) .atCase(s => s.toInt)
from https://stackoverflow.com/questions/34107849/pattern-matching-with-shapeless-coproduct by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] "합니다 MyType"문제 :해야합니까 실제 클래스를 반환하는 스칼라에서 추상적 인 유형 (또는 제네릭)를 사용해야? (0) | 2019.11.28 |
---|---|
[SCALA] 스칼라 : 목록에 튜플 요소를 변환하는 방법 (0) | 2019.11.28 |
[SCALA] 스칼라에서 어떻게 SQL SUM 및 GROUP BY에 해당 할 수 있습니까? (0) | 2019.11.28 |
[SCALA] 놀이! 프레임 워크 : 템플릿에 변수를 정의? [복제] (0) | 2019.11.28 |
[SCALA] 스파크 데이터 세트에서 자신의 reduceByKey 롤링 (0) | 2019.11.28 |