【问题标题】:Gen for a custom data type in Haskell用于 Haskell 中的自定义数据类型的 Gen
【发布时间】:2017-04-13 14:18:20
【问题描述】:

我试图为字符串列表制作一个真值表。 说,我有一个列表 ["a","b"] 作为输出,我想要 [[("a",True),("b",True)], [("a",True),("b",False)], [("a",False),("b",True)], [("a",False),("b",False)]]

真值表中的每个实例都是自定义数据类型,定义为

data TableRow = [(String,Bool)]

有没有更简单的方法?直到现在我一直在这样做


genRow :: [String] -> [TableRow]
genRow [] = []
genRow (x:xs) = ((makeRow x True) : genRow xs) ++ 
            ((makeRow x False) : genRow xs)

很明显,这并没有达到我的预期。请注意,makeRow 只接受 StringBool 并返回 TableRow

有没有更清洁的方法呢?谢谢

【问题讨论】:

  • makeRow 是做什么的?
  • 你是说你想要笛卡尔积两个列表吗?你知道列表推导吗?
  • data TableRow = [(String,Bool)] 无效。您需要一个数据构造函数名称。

标签: haskell functional-programming generator truthtable


【解决方案1】:

您的程序的问题是 genRow :: [String] -> [TableRow] 生成 TableRow 元素列表,并且您不能在 (String,Bool)TableRow 上使用 cons (:) 构造函数,因为 @ 987654326@ 是[[(String,Bool)]]

但是,您可以轻松地使用 list comprehension

genRow :: [String] -> [[(String,Bool)]]
genRow [] = [[]]
genRow (x:xs) = [(x,b):ti | b <- [True,False], ti <- ts]
    where ts = genRow xs

因此,第一条语句应该生成一个包含一个元素的列表:空列表[](结果不是空列表)。此外,我们使用列表推导:我们迭代两个 Bools TrueFalse 以获得 b 并且对于每个这样的值,我们将可能的值迭代为尾部 ts 并将 (x,b) 添加到每个可能的尾巴。

这给出了:

*Main> genRow ["A","B","C"]
[[("A",True),("B",True),("C",True)],
 [("A",True),("B",True),("C",False)],
 [("A",True),("B",False),("C",True)],
 [("A",True),("B",False),("C",False)],
 [("A",False),("B",True),("C",True)],
 [("A",False),("B",True),("C",False)],
 [("A",False),("B",False),("C",True)],
 [("A",False),("B",False),("C",False)]]
*Main> genRow ["Foo","Bar"]
[[("Foo",True),("Bar",True)],
 [("Foo",True),("Bar",False)],
 [("Foo",False),("Bar",True)],
 [("Foo",False),("Bar",False)]]

(为提高可读性添加了新行)

【讨论】:

  • 哇,这很有意义。非常感谢。我不太了解列表推导,也不知道这种特殊的语法。澄清一下,genRow (x:xs) = [(x,b):ti | b &lt;- [True,False], ti &lt;- ts] where ts = genRow xs 这是否有效,因为它在每种情况下为 True 和 False 分别列出了一个列表?
  • 单独的列表是什么意思?
猜你喜欢
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
  • 1970-01-01
相关资源
最近更新 更多