Để lưu quyền người dùng tài khoản bên ngoài (ví dụ: trong DB), tôi muốn trình bày một danh sách các thành phần của một liệt kê có một trường hợp Enum
có nguồn gốc là Int
.
Mỗi bit của số được xem là cờ (hoặc Boolean) biểu thị nếu phần tử thứ i có trong danh sách.
Đặt nó theo các từ khác nhau - mỗi lũy thừa của 2 đại diện cho một phần tử và tổng các quyền hạn đó là danh sách các phần tử độc đáo.Đại diện cho danh sách Enums bitwise dưới dạng Int
Ví dụ:
data Permissions = IsAllowedToLogin -- 1
| IsModerator -- 2
| IsAdmin -- 4
deriving (Bounded, Enum, Eq, Show)
enumsToInt [IsAllowedToLogin, IsAdmin] == 1 + 4 == 5
intToEnums 3 == intToEnums (1 + 2) == [IsAllowedToLogin, IsModerator]
Chức năng chuyển đổi một danh sách như vậy vào một Int
là khá dễ dàng để viết:
enumsToInt :: (Enum a, Eq a) => [a] -> Int
enumsToInt = foldr (\p acc -> acc + 2^fromEnum p) 0 . nub
Lưu ý rằng câu trả lời chấp nhận chứa nhiều hiệu quả hơn thực hiện .
Điều thực sự làm phiền tôi là chức năng đảo chiều. Tôi có thể tưởng tượng rằng nó phải có loại này:
intToEnums :: (Bounded a, Enum a) => Int -> [a]
intToEnums = undefined -- What I'm asking about
Tôi nên tiếp cận vấn đề này như thế nào?
Đối với người mới bắt đầu, có bạn nhìn vào [ 'cái Data.Bits' mô-đun] (http: //hackage.haskell .org/packages/archive/base/mới nhất/doc/html/Data-Bits.html)? –
@C. A. McCann Không, tôi không có! Bạn có nghĩ rằng nó sẽ hữu ích? – Jakub
Tôi không nghĩ rằng nó có bất cứ điều gì làm chính xác những gì bạn muốn (mặc dù nó có vẻ giống như một cái gì đó nên có) nhưng nó có một loạt các hoạt động bitwise mà sẽ làm cho mọi thứ dễ dàng hơn cho bạn. –