Haskell 代码如何在使用列表推导式时利用括号来分隔或整理信息?

How can Haskell code utilise brackets to separate or tidy up information while using list comprehensions?

我正在尝试编写一个函数,其中表达式:

crosswordFind letter inPosition len words

应该 return 来自 words 的所有项目

例如在1位置有’k’的七个字母的单词,表达式:

crosswordFind ’k’ 1 7 ["funky", "fabulous", "kite", "icky", "ukelele"]

将return

["ukelele"]

这是我目前的情况:

crosswordFind :: Char -> Int -> Int -> [String] -> [String]
crosswordFind letter pos len words = 
    if isAlpha **words** == letter && 
        **words** !! letter == pos && 
        length **pos** == len 
    then words 
    else []

上面的代码是在更改以删除我放置的用于分隔每个条件的括号之后。以下代码为原文(错误):

crosswordFind :: Char -> Int -> Int -> [String] -> [String]
crosswordFind letter pos len words =
   [ if [isAlpha x == letter] && 
        [xs !! n == pos] && 
        [length x == len] 
     then words 
     else [] ]

我明白为什么它是错误的(因为长度为 1 的列表将被 returned),但为什么不能使用这样的括号来分隔 Haskell 中的代码?

如何使用列表理解来解决这个问题?我想知道要用什么来替换粗体字以及使代码 运行 正常。

您可以 filter 满足两个条件的条件:

  1. 这个词有给定的长度;和
  2. 位置 pos 上的字符是给定的 letter

对于 words 的单词 w 我们因此检查 length w == lenw !! pos == letter.

因此我们可以通过以下方式实现:

crosswordFind :: Eq a => a -> Int -> Int -> [[a]] -> [[a]]
crosswordFind letter pos len words = filter (\w -> <strong>length w == len && w !! pos == letter</strong>) words

我们也可以省略 words 变量并使用:

crosswordFind :: Eq a => a -> Int -> Int -> [[a]] -> [[a]]
crosswordFind letter pos len = filter (\w -> length w == len && w !! pos == letter)

以上不是很安全:如果 pos 大于或等于长度,那么 w !! pos == letter 将引发错误。此外,对于无限字符串(Char 的列表),length 将永远循环。我把它留作介绍更安全变体的练习。您可以使用递归函数来确定这些。

方括号是列表语法的一部分。没有别的。

列表。

您可以随意使用 round 圆括号 ( ) 来对表达式进行分组。

有些表达式类型,如letdo,有自己的分隔符{;},也可以使用,特别是为了防止空白脆性。