Haskell中数据类型的笛卡尔积

时间:2015-11-13 15:26:36

标签: haskell list-comprehension cartesian-product

尝试将两种数据类型的笛卡尔积产品放入列表中:

 data X = hello | goodbye | hi 
      deriving (ord, enum, eq, show)
 data Y = hello | goodbye | hi 
      deriving (ord, enum, eq, show)

 compList :: [a]
 compList = [(x, y) | x <- X, y <- Y]

显然x&lt; -X等目前不起作用,我只是想知道你们会怎么做呢?

干杯。

2 个答案:

答案 0 :(得分:6)

除了套管问题,并且你不能在这里有两个具有相同名称的数据构造函数,我认为最简单的方法是包含Bounded然后你几乎得到它:

data X = Hello | Goodbye | Hi 
      deriving (Enum, Bounded, Show)

data Y = Hello2 | Goodbye2 | Hi2
       deriving (Enum, Bounded, Show)

compList :: [(X,Y)]
compList = [(x, y) | x <- [minBound..maxBound], y <- [minBound..maxBound]]

使用Enum您可以使用[a .. b]语法(您可能已经知道的内容)和Bounded为您提供minBoundmaxBound

输出

λ> compList
[(Hello,Hello2),(Hello,Goodbye2),(Hello,Hi2),(Goodbye,Hello2),(Goodbye,Goodbye2),(Goodbye,Hi2),(Hi,Hello2),(Hi,Goodbye2),(Hi,Hi2)]

当然,如果你不想使用Bounded,你可以自己给出限制:

data X = Hello | Goodbye | Hi 
      deriving (Enum, Show)

data Y = Hello2 | Goodbye2 | Hi2
       deriving (Enum, Show)

compList :: [(X,Y)]
compList = [(x, y) | x <- [Hello .. Hi], y <- [Hello2 .. Hi2]]

当然,这几乎与[Hello,Goodbye,Hi];)

一样长

答案 1 :(得分:3)

你可以派生出Enum和Bounded。这允许你写:

data X = hello | goodbye | hi
  deriving (Show, Enum, Bounded)

data Y = a | b | c
   deriving (Show, Enum, Bounded)

allX :: [X]
allX = [minBound..maxBound]

allY :: [Y]
allY = [minBound..maxBound]

allXY = [ (x,y) | x <- allX, y <- allY ]