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:我的意思是,获取第二个元素