Tôi đã sau ADT:bản đồ giá trị không phải là thành viên của Chi nhánh [Int]
import cats.Functor
sealed trait Tree[+A]
final case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
final case class Leaf[A](value: A) extends Tree[A]
và làm thực hiện trong functor:
implicit def treeFunctor = new Functor[Tree] {
def map[A, B](fa: Tree[A])(f: (A) => B): Tree[B] =
fa match {
case Branch(left, right) => Branch(map(left)(f), map(right)(f))
case Leaf(v) => Leaf(f(v))
}
}
và sử dụng nó như sau:
val b = Branch(left = Branch(Branch(Leaf(5), Leaf(3)), Leaf(10)), Leaf(45))
val functorTree = Functor[Tree].map(b)((v) => v * 4)
Nhưng theo dõi:
Branch(Leaf(10), Leaf(20)).map(_ * 2)
Tôi đã có lỗi biên dịch:
Error:(21, 29) value map is not a member of A$A90.this.Branch[Int]
Branch(Leaf(10), Leaf(20)).map(_ * 2)
^
Câu hỏi của tôi là tại sao tôi nhận được thông báo lỗi?
Loại 'val b = Branch (left = Branch (Branch (Leaf (5), Leaf (3)), Leaf (10)), Leaf (45))' là Branch [Int] và tại sao tôi có thể chuyển 'b' thành hàm' map' ẩn dụ 'Functor [Tree]'? –
@zero_coding Bởi vì tại thời điểm đó bạn đang chuyển nó đến 'Functor [Tree]' trực tiếp, tương tự như 'ngầm [Functor [Tree]]' (không phải lúc nào, nhưng scalaz và mèo thường có phương thức apply() thuận tiện này cho typeclasses). Vì vậy, nó hoạt động. Nhưng bạn không thể gọi 'map' trên một' Tree', chỉ khi một 'Functor [Tree]' (và bạn đang cố gắng thực hiện trước đây bằng 'Branch (Leaf (10), Leaf (20)). _ * 2) '). Nếu bạn thêm 'toTreeFunctor', Cây của bạn sẽ tự động được chuyển đổi thành Functor [Cây] và nó sẽ là OK. – slouc
@zero_coding Thành thật mà nói, tôi thậm chí không nhận thấy rằng bạn đã có phần 'Functor [Tree] .map' cho đến khi bạn đề cập đến nó trong phần bình luận :) vì vậy hãy bỏ qua phần đầu của câu trả lời của tôi (với 'ngầm ', vì nó giống với' Functor [Tree] .map') của bạn. – slouc