복붙노트

[SCALA] 스칼라의 타입 클래스는 유용 무엇입니까?

SCALA

스칼라의 타입 클래스는 유용 무엇입니까?

나는이 블로그 게시물에서 알고있는 것처럼 스칼라에서 "유형 클래스는"단지 특성과 암시 어댑터 구현 "패턴"입니다.

나는 특성 A와 어댑터 B가있는 경우 블로그가 말한대로 -> A는 그때 명시 적으로이 어댑터를 호출하지 않고 B 형의 인수를 A 형의 인수를 필요로하는 기능을, 호출 할 수 있습니다.

나는 그것이 좋은 있지만 특히 유용하지 발견했다. 이 기능은 유용 보여줍니다 유스 케이스 / 예를 줄 수 있을까요?

해결법

  1. ==============================

    1.하나의 유스 케이스, 요청에 따라 ...

    하나의 유스 케이스, 요청에 따라 ...

    이 목록을 감안할 등 소수점 숫자, 매트릭스, 문자열, 파형, 부동, 정수가 될 수 것들의 목록을 상상해, 당신은 내용을 추가 할.

    것이 이렇게하는 한 가지 방법은 함께 추가 할 수있는 모든 단일 유형, 또는 한 Addable에 암시 적 변환에 의해 상속해야 어떤 한 Addable 특성을 가지고 만약 당신이 인터페이스를 개조 할 수 타사 라이브러리에서 개체를 처리 .

    당신은 또한 개체의 목록을 할 수있는 등의 작업을 추가 시작하고자 할 때이 방법은 신속하게 압도된다. 당신이 대안을 필요로하는 경우에도 잘 작동하지 않습니다 (예를 들어,? 두 개의 파형을 연결하여, 또는 그 오버레이 추가 않습니다) 당신이 선택하고 기존의 유형으로 개조 할 동작을 선택 할 수있는이 솔루션은, 임시 다형성이다.

    다음 원래 문제의 경우, 추가 가능 형 클래스를 구현할 수 :

    trait Addable[T] {
      def zero: T
      def append(a: T, b: T): T
    }
    //yup, it's our friend the monoid, with a different name!
    

    그런 다음 추가 가능한을하고자하는 각 유형에 해당하는이 암시 서브 클래스 인스턴스를 생성 할 수 있습니다 :

    implicit object IntIsAddable extends Addable[Int] {
      def zero = 0
      def append(a: Int, b: Int) = a + b
    }
    
    implicit object StringIsAddable extends Addable[String] {
      def zero = ""
      def append(a: String, b: String) = a + b
    }
    
    //etc...
    

    다음리스트를 요약하는 방법은 단순하게 쓸 ...

    def sum[T](xs: List[T])(implicit addable: Addable[T]) =
      xs.FoldLeft(addable.zero)(addable.append)
    
    //or the same thing, using context bounds:
    
    def sum[T : Addable](xs: List[T]) = {
      val addable = implicitly[Addable[T]]
      xs.FoldLeft(addable.zero)(addable.append)
    }
    

    이 방법의 장점은 당신이 중 하나를 암시 당신이 수입을 통해 범위에서 원하는 제어, 또는 명시 적으로 달리 암시 인수를 제공함으로써, 일부 typeclass의 다른 정의를 제공 할 수 있다는 것입니다. 그래서 추가 파형의 다른 방법을 제공하기 위해, 또는 정수 가산 용 모듈러 연산을 지정하는 것이 가능해진다. 그것은 당신의 typeclass 일부 타사 라이브러리에서 유형을 추가하는 것이 상당히 고통입니다.

    덧붙여, 이것은 2.8 컬렉션 API가 취한 접근 방법은 정확히이다. 합 방법 대신 목록에의 TraversableLike에 정의 및 유형 클래스는 숫자입니다 있지만 (그것도 포함하는 몇 가지 더 작업보다는 단지 제로 및 추가)

  2. ==============================

    2.이 최초의 코멘트를 다시 읽어 본다 :

    이 최초의 코멘트를 다시 읽어 본다 :

    나는이 유형 클래스의 가장 중요한 장점이라고 생각합니다.

    또한, 그들은 작업은 우리가 파견하는 형식의 인수를, 또는 이상이없는 제대로 경우를 처리합니다. 예를 들면 이러한 유형의 클래스를 고려 :

    case class Default[T](val default: T)
    
    object Default {
      implicit def IntDefault: Default[Int] = Default(0)
    
      implicit def OptionDefault[T]: Default[Option[T]] = Default(None)
    
      ...
    }
    
  3. ==============================

    3.나는 클래스에 형태 보증 된 메타 데이터를 추가 할 수있는 기능으로 형 클래스로 생각합니다.

    나는 클래스에 형태 보증 된 메타 데이터를 추가 할 수있는 기능으로 형 클래스로 생각합니다.

    그래서 먼저 문제 도메인을 모델링하는 클래스를 정의하고 다음에 추가 메타 데이터 생각합니다. 등 같음, 해쉬, 가시, 같은 것들이 문제 도메인과 클래스를 사용하는 역학의 분리를 만들고 클래스가 희박하기 때문에 서브 클래스를 엽니 다.

    그를 제외하고, 당신은 클래스가 정의되어 있지 어디서, 범위 어디에서나 타입 클래스를 추가 할 수 있으며 구현을 변경할 수 있습니다. 나는 포인트 # 해시 코드를 사용하여 Point 클래스의 해시 코드를 계산하는 경우 예를 들어, 나는 내가 가지고있는 포인트의 특정 설정 값의 좋은 분포를 만들 수 없습니다 특정 구현에 제한입니다. 내가 해쉬 [포인트]를 사용한다면, 나는 내 자신의 구현을 제공 할 수 있습니다.

    [실시 예에 업데이트] 예를 들어, 여기에 내가 지난 주에 한 사용 사례입니다. 우리의 제품에지도 값으로 컨테이너를 포함하는 여러 가지 경우가 있습니다. 예를 들어, 맵 [INT, 목록 [문자열]] 또는 맵 [문자열, 세트 [지능]. 이러한 컬렉션에 추가하면 자세한 될 수 있습니다 :

    map += key -> (value :: map.getOrElse(key, List()))
    

    그래서 나는 이것이 내가 쓸 수있는 래핑하는 기능을 가지고 싶어

    map +++= key -> value
    

    주요 문제는 컬렉션의 모든 요소를 ​​추가하는 같은 방법이 없다는 것입니다. '+'일부 '+'다른 사람 동안 있습니다. 또한 목록에 요소를 추가의 효율성을 유지하고 싶었다, 그래서 나는 새로운 컬렉션을 만들 배 / 맵을 사용하지 않았다.

    이 솔루션은 유형 클래스를 사용하는 것입니다 :

      trait Addable[C, CC] {
        def add(c: C, cc: CC) : CC
        def empty: CC
      }
    
      object Addable {
        implicit def listAddable[A] = new Addable[A, List[A]] {
          def empty = Nil
    
          def add(c: A, cc: List[A]) = c :: cc
        }
    
        implicit def addableAddable[A, Add](implicit cbf: CanBuildFrom[Add, A, Add]) = new Addable[A, Add] {
          def empty = cbf().result
    
          def add(c: A, cc: Add) = (cbf(cc) += c).result
        }
      }
    

    여기에 내가 수집 CC에 C 원소를 추가 할 수있는 타입의 클래스 한 Addable을 정의했다. 빌더 프레임 워크를 사용하여, 사용 ::을 목록과 다른 컬렉션을 위해 : 나는이 기본 구현이 있습니다.

    그런 다음이 형 클래스이다 사용 :

    class RichCollectionMap[A, C, B[_], M[X, Y] <: collection.Map[X, Y]](map: M[A, B[C]])(implicit adder: Addable[C, B[C]]) {
        def updateSeq[That](a: A, c: C)(implicit cbf: CanBuildFrom[M[A, B[C]], (A, B[C]), That]): That  = {
          val pair = (a -> adder.add(c, map.getOrElse(a, adder.empty) ))
          (map + pair).asInstanceOf[That]
        }
    
        def +++[That](t: (A, C))(implicit cbf: CanBuildFrom[M[A, B[C]], (A, B[C]), That]): That  = updateSeq(t._1, t._2)(cbf)
      }
    
      implicit def toRichCollectionMap[A, C, B[_], M[X, Y] <: col
    

    특수 비트는 요소를 추가 adder.add을 사용하고 adder.empty는 새 키에 대한 새로운 컬렉션을 만들 수 있습니다.

    3 옵션을했을 것이다 I 형 클래스하지 않고, 비교하려면 : 1. 수집 유형별 방법을 작성합니다. 이것은 구현에 상용구를 많이 생성하고 네임 스페이스를 오염 등의 예를 들면, addElementToSubList 및 addElementToSet 2. 서브 컬렉션 목록 / 설정되어 있는지 확인하려면 반사를 사용합니다. 이지도는 처음부터 비어로 까다 롭습니다 (물론 스칼라는 매니페스트와도 여기에 있습니다) 3. 가산기를 제공하도록 사용자에게 요구함으로써 가난한 사람의 유형 클래스가 있습니다. 그래서 추한 일반 addToMap (지도, 키, 값, 가산기), 같은 인

  4. ==============================

    4.그러나 내가 도움이 블로그 게시물을 찾을 수있는 또 다른 방법은 typeclasses을 설명 곳이다 : 모나드는 은유 수 없다

    그러나 내가 도움이 블로그 게시물을 찾을 수있는 또 다른 방법은 typeclasses을 설명 곳이다 : 모나드는 은유 수 없다

    typeclass에 대한 문서를 검색합니다. 그것은 첫 번째 일치해야합니다. 이 글에서 저자는 모나드 typeclass의 예를 제공합니다.

  5. ==============================

    5.포럼 스레드는 "어떤 특성보다는 형 클래스 더 나은 무엇입니까?" 몇 가지 흥미로운 점을합니다 :

    포럼 스레드는 "어떤 특성보다는 형 클래스 더 나은 무엇입니까?" 몇 가지 흥미로운 점을합니다 :

  6. ==============================

    6.타입 클래스를 바라 보는 한 가지 방법은 소급 확장 또는 소급 다형성을 가능하게한다는 것이다. 이를 위해 스칼라의 타입 클래스를 사용하는 예를 보여 캐주얼 기적 다니엘 Westheide하여 큰 게시물의 몇 가지 있습니다.

    타입 클래스를 바라 보는 한 가지 방법은 소급 확장 또는 소급 다형성을 가능하게한다는 것이다. 이를 위해 스칼라의 타입 클래스를 사용하는 예를 보여 캐주얼 기적 다니엘 Westheide하여 큰 게시물의 몇 가지 있습니다.

    여기 내 블로그에 게시물입니다  즉, 예를 포함 typeclass 소급 supertyping 스칼라 다양한 방법 소급 연장의 종류를 탐구한다.

  7. ==============================

    7.여기 가능한 최선의 방법을 설명 애드혹 다형성 이외의 사용 사례를 알고하지 않습니다.

    여기 가능한 최선의 방법을 설명 애드혹 다형성 이외의 사용 사례를 알고하지 않습니다.

  8. ==============================

    8.implicits 및 typeclasses 모두 형식 변환에 사용됩니다. 둘 다에 대한 주요 사용 사례는 수정하지만 다형성의 상속 종류를 기대할 수 없습니다 클래스에 대한 임시 다형성 (즉)을 제공하는 것입니다. implicits의 경우 당신은 (당신의 래퍼 클래스이지만 클라이언트에서 숨겨진하는) 암시 적 데프 또는 암시 적 클래스를 모두 사용할 수 있습니다. (: 스칼라의 정렬 기능에 주문 [T] 등)들이 이미 존재하는 상속 체인에 기능을 추가 할 수 Typeclasses 더 강력하다. 자세한 내용을 위해 당신은 https://lakshmirajagopalan.github.io/diving-into-scala-typeclasses/를 볼 수 있습니다

    implicits 및 typeclasses 모두 형식 변환에 사용됩니다. 둘 다에 대한 주요 사용 사례는 수정하지만 다형성의 상속 종류를 기대할 수 없습니다 클래스에 대한 임시 다형성 (즉)을 제공하는 것입니다. implicits의 경우 당신은 (당신의 래퍼 클래스이지만 클라이언트에서 숨겨진하는) 암시 적 데프 또는 암시 적 클래스를 모두 사용할 수 있습니다. (: 스칼라의 정렬 기능에 주문 [T] 등)들이 이미 존재하는 상속 체인에 기능을 추가 할 수 Typeclasses 더 강력하다. 자세한 내용을 위해 당신은 https://lakshmirajagopalan.github.io/diving-into-scala-typeclasses/를 볼 수 있습니다

  9. ==============================

    9.스칼라 형 클래스에서

    스칼라 형 클래스에서

    행동 확장 할 수 있습니다  - 컴파일시  - 사후  - / 컴파일 기존 코드를 변경하지 않고

    Implicits 스칼라

    방법의 마지막 파라미터리스트는 암시 적으로 표시 될 수있다

    유형 클래스 구현 String 클래스의 예제 확장 아래의 문자열이 마지막에도 불구하고 새로운 방법과 클래스를 확장 :)

    /**
    * Created by nihat.hosgur on 2/19/17.
    */
    case class PrintTwiceString(val original: String) {
       def printTwice = original + original
    }
    
    object TypeClassString extends App {
      implicit def stringToString(s: String) = PrintTwiceString(s)
      val name: String = "Nihat"
      name.printTwice
    }
    
  10. ==============================

    10.이것은 중요한 차이 (함수형 프로그래밍에 필요한)입니다 :

    이것은 중요한 차이 (함수형 프로그래밍에 필요한)입니다 :

    나는 INC을 고려 : 민의 A => A -> A :

    수신 된 반환되는 동일이는 하위 유형으로 수행 할 수 없습니다

  11. ==============================

    11.난 여전히 코드의 복잡성을 많이 추가하지 않습니다 아직 순환 종속성이 작동 의존성 삽입 (Dependency Injection)의 경량 스칼라 관용적 형태로 타입의 클래스를 사용하는 것을 좋아합니다. 최근 DI 클래스가 입력 케이크 패턴을 이용하여 스칼라에서 프로젝트를 재 작성 및 코드 크기에서 59 % 감소를 달성했다.

    난 여전히 코드의 복잡성을 많이 추가하지 않습니다 아직 순환 종속성이 작동 의존성 삽입 (Dependency Injection)의 경량 스칼라 관용적 형태로 타입의 클래스를 사용하는 것을 좋아합니다. 최근 DI 클래스가 입력 케이크 패턴을 이용하여 스칼라에서 프로젝트를 재 작성 및 코드 크기에서 59 % 감소를 달성했다.

  12. from https://stackoverflow.com/questions/5408861/what-are-type-classes-in-scala-useful-for by cc-by-sa and MIT license