List Haskell中列表列表中元素的筛选器

List Haskell中列表列表中元素的筛选器,list,haskell,filter,List,Haskell,Filter,我建立了这个结构的列表: [(Interger, Double)] 该列表是通过在整数列表和大小完全相同的双精度列表上使用zip创建的 现在,我想过滤列表中25的双打。我的问题是我无法访问double来在filter函数中使用它们 这可能很容易,但我在这门语言中是个该死的笨蛋。我在谷歌上搜索了很多,读了一些其他的帖子,但没有找到答案 我得到: filter (<18.5) listexpression filter(您可以执行以下操作: Prelude> filter (\p -

我建立了这个结构的列表:

[(Interger, Double)]
该列表是通过在整数列表和大小完全相同的双精度列表上使用zip创建的

现在,我想过滤列表中25的双打。我的问题是我无法访问double来在filter函数中使用它们

这可能很容易,但我在这门语言中是个该死的笨蛋。我在谷歌上搜索了很多,读了一些其他的帖子,但没有找到答案

我得到:

filter (<18.5) listexpression

filter(您可以执行以下操作:

Prelude> filter (\p -> (snd p) < 18.5 || (snd p) > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
表示对于每个
p
,p
的第二个元素必须小于18.5或大于25


或者,你可以这样写

Prelude> filter (\(_, f) -> f < 18.5 || f > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
Prelude>filter(\(\,f)->f<18.5 | | f>25)[(1,2.3)、(1,20.0)]
[(1,2.3)]

这里的函数表示,对于第一个值无关紧要,第二个值为
f
f
的任何一对,其值必须小于18.5或大于25。

您可以这样做:

Prelude> filter (\p -> (snd p) < 18.5 || (snd p) > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
表示对于每个
p
,p的第二个元素必须小于18.5或大于25


或者,你可以这样写

Prelude> filter (\(_, f) -> f < 18.5 || f > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
Prelude>filter(\(\,f)->f<18.5 | | f>25)[(1,2.3)、(1,20.0)]
[(1,2.3)]

这里的函数表示,对于第一个值无关紧要,第二个值为
f
f
的任何一对,必须小于18.5或大于25。

使用无点样式的紧凑版本将是

 filter ((>18.5).snd) listexpression

这使用函数组合运算符
,其内容如下:首先将
snd
函数应用于列表中的元组,以提取第二个值,然后将与18.5的比较应用于该值。

使用无点样式的紧凑版本将是

 filter ((>18.5).snd) listexpression
这将使用函数组合运算符
,其内容如下:首先将
snd
函数应用于列表中的元组,以提取第二个值,然后将18.5的比较值应用于该值。

很高兴看到您的问题得到了解决

但在这个答案下,你评论道:

我尝试使用(!!)组合访问它,但没有成功

有了助教的洞察力,我猜你把Haskell的
list
tuple
搞混了

zip
返回
元组的
列表
,而
(!!)
列表
作为(第一个)参数(因此
(!!1)
使用单个
列表
参数),因此
(!!1)
无法应用于
zip
返回的
列表的元素,这些元素属于
元组类型

Prelude> :t zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> :t (!!1)
(!!1) :: [a] -> a
Prelude> :t fst
fst :: (a, b) -> a
Prelude> :t snd
snd :: (a, b) -> b
您已经知道,
fst
snd
应用于
tuple

Prelude> :t zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> :t (!!1)
(!!1) :: [a] -> a
Prelude> :t fst
fst :: (a, b) -> a
Prelude> :t snd
snd :: (a, b) -> b
很高兴看到你的问题解决了

但在这个答案下,你评论道:

我尝试使用(!!)组合访问它,但没有成功

有了助教的洞察力,我猜你把Haskell的
list
tuple
搞混了

zip
返回
元组的
列表
,而
(!!)
列表
作为(第一个)参数(因此
(!!1)
使用单个
列表
参数),因此
(!!1)
无法应用于
zip
返回的
列表的元素,这些元素属于
元组类型

Prelude> :t zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> :t (!!1)
(!!1) :: [a] -> a
Prelude> :t fst
fst :: (a, b) -> a
Prelude> :t snd
snd :: (a, b) -> b
您已经知道,
fst
snd
应用于
tuple

Prelude> :t zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> :t (!!1)
(!!1) :: [a] -> a
Prelude> :t fst
fst :: (a, b) -> a
Prelude> :t snd
snd :: (a, b) -> b

只是为了一个品种和一些额外的信息,不会咬

在Haskell.So中,像
filter
这样的列表操作可以简单地由一元绑定操作符实现

*Main> [(1,2.3),(3,21.2),(5,17.1),(4,24.4)] >>= \t -> if snd t < 25 && snd t > 18.5 then [t] else []
[(3,21.2),(4,24.4)]
一元绑定运算符的类型签名表示它将一元类型值
ma
作为第一个参数(此处为元组列表),并将一个函数作为第二个参数,该参数采用纯值并返回一元值(在本例中,采用元组并返回列表中的元组或空列表)

当然,这与列表理解非常相似,列表理解实际上是一元列表操作的语法糖。因此,让我们最后一次使用列表理解来实现它

*Main> [t | t <- [(1,2.3),(3,21.2),(5,17.1),(4,24.4)], snd t < 25 && snd t > 18.5]
[(3,21.2),(4,24.4)]
*Main>[t|t 18.5]
[(3,21.2),(4,24.4)]

只为各种各样的内容和一些不会产生影响的附加信息

在Haskell.So中,像
filter
这样的列表操作可以简单地由一元绑定操作符实现

*Main> [(1,2.3),(3,21.2),(5,17.1),(4,24.4)] >>= \t -> if snd t < 25 && snd t > 18.5 then [t] else []
[(3,21.2),(4,24.4)]
一元绑定运算符的类型签名表示它将一元类型值
ma
作为第一个参数(此处为元组列表),并将一个函数作为第二个参数,该参数采用纯值并返回一元值(在本例中,采用元组并返回列表中的元组或空列表)

当然,这与列表理解非常相似,列表理解实际上是一元列表操作的语法糖。因此,让我们最后一次使用列表理解来实现它

*Main> [t | t <- [(1,2.3),(3,21.2),(5,17.1),(4,24.4)], snd t < 25 && snd t > 18.5]
[(3,21.2),(4,24.4)]
*Main>[t|t 18.5]
[(3,21.2),(4,24.4)]

谢谢!我知道这个问题对于经验稍丰富的人来说很简单。我知道匿名函数,但不知道“snd”。我尝试使用(!!)组合访问它,但没有效果。我会尽快接受你的答案:)@Shadol你也不需要知道
snd
,因为模式匹配通常更可取。在这种情况下,它肯定更可取。它甚至可以与我自己创建的过滤功能一起工作:D@leftaroundabout如果通过“模式匹配”,您指的是类似我在这里创建的Ackermann函数:
ackerF m n | m==0=n+1 | m>0&&n==0=ackerF(m-1)1 | m>0&&n>0=ackerF(m-1)(ackerF m(n-1))
那么我仍然不知道如何使用这些知识访问我想要的元素。@Shadol:我的意思是,获取第二个元素