2012-01-11 40 views
6

Có thể làm như sau:Câu lệnh kiểu có phạm vi có thể không?

foo = bar 
    where 
     type A = (Some, Huge, Type, Sig) 

     meh :: A -> (A, A) -> A 

Tôi chỉ cần sử dụng loại tùy chỉnh này trong mệnh đề where, vì vậy nó không có ý nghĩa để xác định nó trên toàn cầu.

+0

Tôi cho rằng điều này giả định rằng 'meh' không phải là đa hình? –

Trả lời

8

Điều này là không thể. Tại sao không chỉ xác định nó ở trên hàm? Bạn không phải xuất nó từ mô-đun (chỉ cần sử dụng một danh sách xuất khẩu rõ ràng).

Nhân tiện, nếu bạn thực sự có loại lớn, có thể là dấu hiệu cho thấy bạn nên đặt nó vào các phần nhỏ hơn, đặc biệt nếu bạn có nhiều bộ dữ liệu như ví dụ của bạn; các kiểu dữ liệu sẽ thích hợp hơn.

8

Trên thực tế, có một, hơi vô lý, cách để xấp xỉ này:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE ScopedTypeVariables #-} 

foo :: forall abbrv. (abbrv ~ (Some, Huge, Type, Sig)) 
    => abbrv -> abbrv 
foo x = meh x (x, x) 
    where meh :: abbrv -> (abbrv, abbrv) -> abbrv 
     meh x y = {- ... -} 

tôi có thể không thực sự khuyên cho phép hai phần mở rộng ngôn ngữ chỉ vì lợi ích của abbreviating loại trong chữ ký, mặc dù nếu bạn đã sử dụng chúng (hoặc GADT thay vì gia đình kiểu) Tôi cho rằng nó không thực sự làm tổn thương gì cả.

Sang một bên, bạn nên xem xét sắp xếp lại các loại của mình trong các trường hợp như thế này, như ehird gợi ý.

+1

Rất dễ thương! Các biến kiểu phạm vi có thực sự cần thiết không? (Có vẻ như sự bình đẳng kiểu là bit thực sự thông minh, và điều đó có thể được chuyển thành kiểu 'meh'.) –

+0

Bạn quên' RankNTypes'. – ehird

+0

@DanielWagner: Chỉ có ràng buộc bình đẳng là bắt buộc đối với mẹo viết tắt, vâng. Nhưng câu hỏi đặc biệt về kiểu * scoped *, vì vậy không mở rộng nó đến mệnh đề 'where' sẽ không hài lòng. :] –

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