用于检查排列的 Haskell 函数
Posted
技术标签:
【中文标题】用于检查排列的 Haskell 函数【英文标题】:Haskell function to check permutation 【发布时间】: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
【问题讨论】:
【参考方案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]
。以上是关于用于检查排列的 Haskell 函数的主要内容,如果未能解决你的问题,请参考以下文章