2015-05-30 14 views
5

Đây là câu hỏi kiểu mã hóa chứ không phải là câu hỏi kỹ thuật.Đặt tên xung đột giữa giá trị trường và phạm vi địa phương trong Haskell

Tôi thường gặp phải sự cố khi sử dụng cú pháp bản ghi (ít nhất là tối ưu) của haskell (hoặc ống kính, sự cố kết thúc giống nhau) để tạo loại data. Tôi kết thúc với các hàm truy cập trường được đặt tên theo các trường của tôi. Là một lập trình viên tận tâm, tôi cố gắng làm cho tên trường hồ sơ của tôi có ý nghĩa.

Tại một thời điểm nào đó sau đó, tôi cần lấy trường ra khỏi loại của mình và giữ giá trị của nó trong biến cục bộ. Điều này thường được thực hiện trong một StateMonad trong một khối do. Câu hỏi đặt ra là tôi gọi biến cục bộ là gì. Tên rõ ràng nhất đã được dùng làm accessor trường. Tôi thấy tự mình sử dụng các từ viết tắt có xu hướng làm cho mã của tôi ít đọc được hơn.

Có quy ước mã hóa Haskell giải quyết vấn đề này không?

Ví dụ

data Qaax = Qaax { 
     foo :: SomeFoo 
    , bar :: SomeBar 
    , ... 
    } 

baz :: (MonadState Qaax m) => (...) -> m() 
baz (...) = do 
    f <- gets foo -- I'd really like to use something more descriptive then 
       -- `f` but `foo` is already taken. 
    ... 
    return() 

Trả lời

3

Thêm 'dưới dạng hậu tố là quy ước được thiết lập để tạo các tên riêng biệt nhưng có liên quan. Ví dụ chính là foldlfoldl'.

Trong tên đã xuất như foldl' thường là một ý tưởng tốt để đưa ra chủ đề phù hợp cho ý nghĩa của thư viện (thường là "phiên bản nghiêm ngặt hơn", như trong foldl'). Nhưng trong tên địa phương bạn có thể tự do hơn rất nhiều để chỉ sử dụng nó "một điều liên quan chặt chẽ khác tôi muốn có cùng tên như".

Nhược điểm là nó không phải là rất riêng biệt, vì vậy nó có thể làm tổn thương khả năng đọc; đặc biệt là nếu bạn cần thường tham chiếu đến cả hai phiên bản. Và khi bạn thấy mình cần foo''', bạn có lẽ nên suy nghĩ về một kế hoạch đặt tên khác!

2

Việc gia hạn NamedFieldPuns có thể giúp với điều này. Khi mô hình khớp vào một kỷ lục, nó liên kết với một biến với tên giống như một cánh đồng kỷ lục:

{-# LANGUAGE NamedFieldPuns #-} 

baz :: (MonadState Qaax m) => m() 
baz = do 
    Qaax {foo} <- get 
    return() 

Một vấn đề có thể là do accessor được shadowed cho phần còn lại của khối do.

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