Haskell 冗余模式匹配警告

Haskell 冗余模式匹配警告,haskell,pattern-matching,Haskell,Pattern Matching,我正在写一段代码,这是一个函数返回 像素列表是我定义的一种特殊数据类型,具有以下特征: data Pixel = Pixel { color :: Float, elevation :: Float, distance: Float, visited :: Bool } deriving (Show)

我正在写一段代码,这是一个函数返回 像素列表是我定义的一种特殊数据类型,具有以下特征:

data Pixel = Pixel {
                    color :: Float,
                    elevation :: Float,
                    distance: Float,
                    visited :: Bool
                   } deriving (Show)
我有一个函数,它将遍历两个文件,并将它们放在一个像素列表中。这些文件分别包含颜色和高程,因此我继续获取以下代码输出:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels _ _ = []
insertPixels (x:xs) (y:ys) = [Pixel (read x) (read y) 99999999 False] ++ insertPixels xs ys
当我试图编译此文件或将其加载到解释器中时,我收到以下错误:

lab1.hs:33:1: warning: [-Woverlapping-patterns]
Pattern match is redundant
In an equation for ‘insertPixels’:
    insertPixels (x : xs) (y : ys) = ...
|
| insertPixels (x:xs) (y:ys) = [Pixel (read x) (read y) 99999999 False] ++ insertPixels xs ys
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我真的不明白这是什么意思,也不明白我做错了什么。

只需将两行的顺序转换一下,如下所示:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels (x:xs) (y:ys) = [Pixel (read x) (read y) 99999999 False] ++ insertPixels xs ys
insertPixels _ _ = []
问题是,
insertPixels\uuuu\uuu
匹配所有内容,而且由于模式是自上而下计算的,在第一次匹配时停止,所有可能的输入都会导致空列表-显然不是您想要的。如前所述,只要两个输入列表都是非空的,递归情况就会生效,一旦其中一个列表为空,它就会变成“catch all”情况,并导致空列表

作为旁注,使用
(++)
操作符向列表的开头添加单个元素并不是特别习惯用法。您可以改用
(:)
(“cons”)运算符:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels (x:xs) (y:ys) = (Pixel (read x) (read y) 99999999 False) : insertPixels xs ys
insertPixels _ _ = []

只需切换两行的顺序,如下所示:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels (x:xs) (y:ys) = [Pixel (read x) (read y) 99999999 False] ++ insertPixels xs ys
insertPixels _ _ = []
问题是,
insertPixels\uuuu\uuu
匹配所有内容,而且由于模式是自上而下计算的,在第一次匹配时停止,所有可能的输入都会导致空列表-显然不是您想要的。如前所述,只要两个输入列表都是非空的,递归情况就会生效,一旦其中一个列表为空,它就会变成“catch all”情况,并导致空列表

作为旁注,使用
(++)
操作符向列表的开头添加单个元素并不是特别习惯用法。您可以改用
(:)
(“cons”)运算符:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels (x:xs) (y:ys) = (Pixel (read x) (read y) 99999999 False) : insertPixels xs ys
insertPixels _ _ = []

下划线
\uuu
是一个通配符,这意味着它匹配任何内容:空列表、非空列表等

因此,这意味着无论传递给
insertPixels
的值是什么,第一行都将“激发”。没有第二行将“激发”的输入模式,因此发出警告

我们可以在空列表上使用模式匹配,例如:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels [] _ = []
insertPixels _ [] = []
insertPixels (x:xs) (y:ys) = [Pixel (read x) (read y) 99999999 False] ++ insertPixels xs ys
然而,你在这里描述的是一个众所周知的模式。A.因此,我们可以将插入像素定义为:

import Data.Function(on)

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels = zipWith (\x y -> on Pixel read x y 99999999 False)

但是,我建议从
insertPixels
函数中删除
read
,从而使用两个
Float
s列表。如果要使用
读取
,则可以在调用方级别执行该操作。

下划线
\u
是一个通配符,这意味着它匹配任何内容:空列表、非空列表等

因此,这意味着无论传递给
insertPixels
的值是什么,第一行都将“激发”。没有第二行将“激发”的输入模式,因此发出警告

我们可以在空列表上使用模式匹配,例如:

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels [] _ = []
insertPixels _ [] = []
insertPixels (x:xs) (y:ys) = [Pixel (read x) (read y) 99999999 False] ++ insertPixels xs ys
然而,你在这里描述的是一个众所周知的模式。A.因此,我们可以将插入像素定义为:

import Data.Function(on)

insertPixels :: [String] -> [String] -> [Pixel]
insertPixels = zipWith (\x y -> on Pixel read x y 99999999 False)

但是,我建议从
insertPixels
函数中删除
read
,从而使用两个
Float
s列表。如果您想使用
read
,那么您可以在调用者级别执行此操作。

您可能还喜欢
zipWith
,如
insertPixels=zipWith(\x y->Pixel(read x)(read y)999999 False)
。您也可能喜欢
zipWith
,如
insertPixels=zipWith(\x y->Pixel(read x)(read y)999999 False)
。谢谢。我有一个问题,Haskell是否扩展了所有内容,然后创建了列表,还是在每次迭代中都创建了一个新的列表?我不太确定你在问什么。但是Haskell通常是懒惰的,这意味着它在真正需要计算之前不会计算任何东西(通常需要打印出来)。对于列表,它将只计算任意点所需的列表元素数。谢谢。我有一个问题,Haskell是否扩展了所有内容,然后创建了列表,还是在每次迭代中都创建了一个新的列表?我不太确定你在问什么。但是Haskell通常是懒惰的,这意味着它在真正需要计算之前不会计算任何东西(通常需要打印出来)。对于列表,它将只计算任意点所需的列表元素数。谢谢。我试试这个。谢谢。我试试这个。