为了将用户账户权限保存在外部(例如在数据库中),我想要用一个枚举的元素列表来表示具有派生
数字的每一位被视为一个标志(或布尔值),表示第i个元素是否存在于列表中。
换句话说,2的幂代表一个元素,这些幂的总和是一个唯一元素列表。
将这样一个列表转换为
我该如何解决这个问题?
Enum
实例的Int
。数字的每一位被视为一个标志(或布尔值),表示第i个元素是否存在于列表中。
换句话说,2的幂代表一个元素,这些幂的总和是一个唯一元素列表。
例如:
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]
将这样一个列表转换为
Int
的函数很容易编写:enumsToInt :: (Enum a, Eq a) => [a] -> Int
enumsToInt = foldr (\p acc -> acc + 2 ^ fromEnum p) 0 . nub
请注意,被采纳的答案包含一个更有效的实现。
真正困扰我的是反转函数。 我可以想象它应该具有这种形式:
intToEnums :: (Bounded a, Enum a) => Int -> [a]
intToEnums = undefined -- What I'm asking about
我该如何解决这个问题?
Data.Bits
module 了吗? - C. A. McCann