使用列表推导时,如何获取列表而不是列表元素类型?

时间:2018-02-06 01:18:13

标签: haskell list-comprehension

我在编写一个从用户那里获取字符串的函数时收到错误并决定返回bool是否是pangram。我因此错误而出现并发症

"无法将预期类型的​​Char与实际类型[Char]"匹配。

这是我在.hs文件中的所有代码。

lowerlist = ['a'..'z']
upperlist = ['A'.. 'Z']
tlist = zip upperlist lowerlist

pangram s = [if xs == lowerlist then True else False| xs <- lowerlist, xs `elem` s]

如果我把[]放在xs周围,那么它只会给我一堆&#34; [真,假,真,真,.....]&#34;。

有人可以帮我解决这个问题,或许可以给我一些关于这个程序的提示吗?

1 个答案:

答案 0 :(得分:1)

首先,你问的字面问题的答案。在列表解析中引用列表本身的方法是给它一个绑定。举例说明:

a2z = 'a':[ succ (a2z!!i) | i <- [0..24]]
fibo = 0:1:[fibo !! i + fibo !! (i+1) | i <- [0..]]

现在,pangram计划。它看起来好像你想要提示自己解决它,而不是一个完整的解决方案,所以:你想要的不是将你的字符串与文字字母表进行比较,而是测试基于输入字符串的谓词是否对于每个字符都是正确的字母表。也就是说,您的谓词是输入的某些函数,对于字母表中的all个字符必须为true。您可以尝试填写此骨架中的洞:

import Data.Char (toLower)

main :: IO ()
main = interact ( unlines . map show . map isPangram . lines )

isPangram :: String -> Bool
isPangram xs = all (_ ys) alphabet
  where alphabet = ['a'..'z']
        ys = map toLower xs

正如GHC告诉你的那样,缺失函数的类型是:: String -> Char -> Bool。所以你也可以这样写:

import Data.Char (toLower)

main :: IO ()
main = interact ( unlines . map show . map isPangram . lines )

isPangram :: String -> Bool
isPangram xs = all p alphabet
  where alphabet = ['a'..'z']
        ys = map toLower xs

        p :: Char -> Bool
        p c = _

您可以删除ys参数,只需在ys内直接引用p,因为保存规范化输入的变量位于p范围内。

也许你想要调整当前的程序。在这种情况下,您生成的列表是Bool的列表。如果列表包含字母表中每个字母的True,如果该字母出现在输入中,False(如果不是),则可以使程序正常工作。您还可以使用all将此列表缩减为单个布尔值。

如果您想要累积到目前为止在字符串中遇到的所有字母的集合,并且当它等于整个字母表时停止,则需要更复杂的递归尾递归函数。它会将其累积参数构建为插入Data.List.Ordered之类的内容,确保仅插入字母表中的元素,每个元素只插入一次,并在累积集合的基数(即length时停止)有序列表)与字母表相同。但是,从完整的字母表开始并在遇到元素时删除元素会更有效,当输入或字母表为空时停止:

import Data.Char (toLower)
import Data.List -- You’ll need a function from here.

main :: IO ()
main = interact ( unlines . map show . map isPangram . lines )

isPangram :: String -> Bool
isPangram xs = isPangram' alphabet ys
  where alphabet = ['a'..'z']
        ys = map toLower xs

        isPangram' :: [Char] -> [Char] -> Bool
        isPangram' [] _ = _  -- There are no more letters to search for.
        isPangram' _ [] = _ -- There is nothing left to search.
        isPangram' ws (z:zs) = isPangram' _ _ -- Remove an element from both lists.

另一种方法是将输入标准化,filter排除所有无关元素,并将剩下的nub作为Char的列表。

相关问题