2016-06-26 16 views
5

Tôi luôn tin rằng các bí danh loại luôn mở rộng thành loại ban đầu của chúng nếu cần. Nhưng, đây là một rốiBí danh loại Scala phá vỡ tính tương thích kiểu

def a[P](a: Option[P]) = { 
    type Res = List[P] // result type alias 
    Nil: Res // Replace this line with Nil: List[P] to clear the error 
} 
def b[V](v: V) = a(Some(v)): List[V] 

nó không thành công với (scastie)

error: type mismatch; 
found : Res (which expands to) List[P] 
required: List[V] 

Bạn thấy rằng a chuyển đổi Option[P] => List[P] và, vì b nguồn cung cấp Some[V], a chuyển đổi Option[V] => List[V] khi b gọi nó. Nhưng, trình biên dịch nói rằng kết quả không tương thích với List[V]. Sao có thể như thế được? Lỗi này biến mất (scastie) nếu bạn thay thế Nil: Res bằng Nil: List[P] trong a. Bạn cần loại bỏ bí danh loại để loại bỏ lỗi. Điều này có nghĩa là bí danh loại là thủ phạm.

+1

Thậm chí nếu đó là lỗi trình biên dịch, thật kỳ lạ và khó hiểu khi khai báo một bí danh loại bên trong một phương thức và sử dụng nó để suy ra loại trả về của nó. –

+0

@ m-z Tôi vừa sử dụng nó trong [recurion parsing argument] (http://stackoverflow.com/questions/38037089). Nói với nó là sai và bạn biết cách tốt hơn nhiều. Trên thực tế, đây là một phong cách lập trình được thúc đẩy bởi khóa học Corusera của Oderki. Họ dạy bạn rằng nếu bạn không làm foldLeft, bạn làm một đệ quy. Recursion là Workhorse có thể làm mọi thứ nếu không có phương tiện đặc biệt nào để lặp lại không gian thiết kế được cấp phép. Phép đệ quy có nghĩa là bạn có một hàm mặt tiền, mà chấp nhận các cuộc gọi từ người dùng nhưng việc thực hiện thực tế được thực hiện bởi hàm đệ quy 'nội bộ'. –

+0

Tức là, mẫu chức năng cơ bản là 'def facade (args) = {def worker (lặp, accumulator: ResType): ResType = if (done) acc else {.recursion.}; worker (starting args)} 'Như bạn thấy,' acc' của nhân viên khớp với kiểu kết quả và bạn buộc phải khai báo kiểu kết quả công nhân trong Scala. Đó là, bạn cần phải xác định loại kết quả của bạn hai lần khi mã hóa mặt tiền. Xin vui lòng downvote để hiển thị rằng sau DRY nó là sai trong mô hình FP cơ bản nhất và tiết kiệm cho chúng tôi từ thực hành lập trình xấu. Nói rằng nhân viên đó phải được khai báo bên ngoài. Nói rằng loại inferece từ bên trong là một mùi hôi. –

Trả lời

0

Tôi gần như chắc chắn đây là lỗi trình biên dịch. Nhập bí danh trong Scala được cho là tự động mở rộng và có vẻ như trong trường hợp này loại a được suy ra là [P](Option[P]) => Res, thay vì [P](Option[P]) => List[P]. Và vì Res nằm trong phạm vi bên trong, trình biên dịch không thể tìm thấy nó để suy ra loại b chính xác.

Các vấn đề liên quan