【问题标题】:Haskell function to check permutation用于检查排列的 Haskell 函数
【发布时间】:2015-12-16 07:04:37
【问题描述】:

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

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

【问题讨论】:

    标签: function haskell boolean permutation


    【解决方案1】:

    试试这个:

    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
    

    希望对您有所帮助。

    【讨论】:

    • 您可以通过添加Ord 约束并使用集合而不是nub 来提高效率(如果这是一个问题)。
    • 我是否需要在 if 语句中以某种方式将“checkPermutation f = (== length urban).length .nub .map f $citys”放在一个 if 语句中,以便我可以返回 true 或 false?此外,ghci 不喜欢“cities = [Baltimore..Toronto]”,说部分必须用括号括起来,而不是在范围内
    • @user2988976 不,(== length cities) 函数本身返回一个布尔值。此外,如果您使用 GHCi,则需要输入 let cities = [Baltimore..Toronto]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-03-06
    • 2012-04-15
    • 2017-12-04
    • 2022-11-29
    • 2020-03-09
    相关资源
    最近更新 更多