繁体   English   中英

Haskell 定义列表和列表理解

[英]Haskell Defining a List and List Comprehension

早上好!

我正在尝试定义一个列表,该列表包含我之前定义的所有可能的地址类型,并使用列表理解来执行此操作。

以下是我对早期定义的了解,可能对您有所帮助:

data Row = A | B | C | D | E | F | G | H | I | J deriving (Enum, Ord, Show, Bounded, Eq, Read)
data Column = One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten  deriving (Enum, Ord, Show, Bounded, Eq, Read)
data Address = Address Row Column deriving (Show, Read, Eq)
data Cell = Cell Address Bool deriving (Show, Read, Eq)

我不确定是否需要在此解决方案中使用 Cell,但也许可以。

这是我目前的解决方案,我想知道是否有人对改进它有建议,或者它可能完全错误。 任何指导将不胜感激!

allAddressesA = [ x * y | x <- [Row] y <- [Column]]

仅供参考,这里有一个正式的书面要求:

将 allAddressesA 定义为所有可能的板地址的列表。 使用使用行和列类型范围的列表理解。

谢谢! 我将密切关注此事,因此请随时提出任何您需要澄清的问题以提供帮助。 感谢您花时间阅读本文并可能提供建议:)

你写:

这是我目前的解决方案,我想知道是否有人对改进它有建议,或者它可能完全错误。

是否完全错误当然可以很容易地测试。 只需输入它并询问您的编译器:

allAddressesA = [ x * y | x <- [Row] y <- [Column]]

我的 说:

parse error on input `<-'

我想这是错误的。

因此,让我们首先修复语法。 列表推导式的第二部分(即|之后的部分)中可能有多个子句用逗号分隔。 这样做给出:

allAddressesA = [ x * y | x <- [Row], y <- [Column]]

编译器对此有何看法?

Not in scope: data constructor `Row'
Not in scope: data constructor `Column'

事实上, RowColumn是类型构造器而不是数据构造器。 这意味着您可以使用它们来构建类型表达式,但不能构建“普通”值表达式。

显然,我们走在错误的道路上。 所以让我们退后几步。

你的Row类型和你的Column类型都在类型类EnumBounded 因此,我们可以轻松地分别生成具有所有行和列指示符的列表:

allRows    = [minBound :: Row    .. maxBound]
allColumns = [minBound :: Column .. maxBound]

(分别使用minBoundmaxBound使您的代码比立即使用AJ以及OneTen更健壮,因为向RowColumn添加构造函数不需要您更改allRowsallColumns的定义。)

在交互式环境中,我们可以轻松评估这些列表。 事实上,打印allRows给出:

> allRows
[A,B,C,D,E,F,G,H,I,J]

对于allColumns我们得到

> allColumns
[One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten]

现在,由于地址由行和列指示符组成,因此生成所有可能的地址简单地简化为取所有行和所有列的叉积。 有了之前对allRowsallColumns定义,我们可以轻松地编写这样的交叉产品作为列表allColumns

allAddresses = [Address row column | row <- allRows, column <- allColumns]

由于您有 10 个行指示符和 10 个列指示符,您最终会得到一个 10 x 10 = 100 个地址的列表:

> length allAddresses
100

为了消遣,让我们打印前 15 个:

> take 15 allAddresses
[Address A One,Address A Two,Address A Three,Address A Four,Address A Five,
Address A Six,Address A Seven,Address A Eight,Address A Nine,Address A Ten,
Address B One,Address B Two,Address B Three,Address B Four,Address B Five]

这是您的代码的骨架:

allAddressesA = [ Address {- ... -} | x <- [A .. J], y <- [ {- ... -} ]]

用正确的代码替换每个{- ... -}

data Address = Address Row Column

意味着您可以通过使用名为Address的构造函数来创建Address类型的复合数据,该函数需要两个参数:第一个参数为Row ,第二个参数为Column 在指定范围时,我们显示数据元素,而不是类型或课程:我们写[1 .. 10] ,而不是[Int]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM