用于检查排列的Haskell函数

时间:2015-09-19 03:05:37

标签: function haskell boolean permutation

如果我声明数据构造函数,例如

data City = Baltimore | Chicago | Seattle | Miami | Toronto
        deriving (Bounded, Enum, Eq, Ord, Show)

data Name = Orioles | Cubs | Mariners | Marlins | BlueJays
        deriving (Bounded, Enum, Eq, Ord, Show)

如何制作功能

checkPermutation :: (City -> Name) -> Bool

检查没有为两个城市分配相同的团队名称。例如,以下内容将返回True,但如果将任何“名称”分配给多个城市,则返回False。

test1 :: City -> Name
test1 c = case c of
    Baltimore  -> Orioles
    Chicago    -> Cubs
    Seattle    -> Mariners
    Miami      -> Marlins
    Toronto    -> Blue Jays

1 个答案:

答案 0 :(得分:5)

试试这个:

import Data.List (nub)

cities :: [City]
cities = [Baltimore..Toronto]

checkPermutation :: (City -> Name) -> Bool
checkPermutation f = (== length cities) . length . nub . map f $ cities

这基本上检查函数f :: City -> Name是否为injective

事实上,我们可以创建更通用的injective谓词:

import Data.Set as Set

typeSet :: (Bounded a, Enum a, Ord a) => Set a
typeSet = fromList $ enumFrom minBound

injective :: (Enum a, Bounded a, Ord a, Ord b) => (a -> b) -> Bool
injective f = let xs = typeSet in (== size xs) . size . Set.map f $ xs

希望有所帮助。