我建立了这个结构的列表:
[(Interger, Double)]
List是使用整数列表上的zip和完全相同大小的双打列表创建的。
现在我想过滤掉< 18.5或> 25的双打列表。我遇到的问题是我无法访问双打在过滤功能中使用它们。
这可能很容易,但我是这种语言的血腥菜鸟。我搜索了很多并阅读了其他一些帖子,但我找不到答案。
我得到了:
filter (<18.5) listexpression
所以我正在努力的是那种倾听。如果它是单个值的列表,那很容易。我可以在压缩之前进行过滤,但之后我无法将已过滤列表中的数据连接到其他未过滤的列表。
编辑:我忘了提。这是一张工作表。我们被要求自己构建过滤器和映射函数,不允许对基本Haskell使用任何添加。意思是不允许进口。
答案 0 :(得分:5)
您可以这样做:
Prelude> filter (\p -> (snd p) < 18.5 || (snd p) > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
传递给filter
的{{3}},即
(\p -> (snd p) < 18.5 || (snd p) > 25)
表示对于每p
,p
的第二个元素必须小于18.5或超过25。
或者,您可以像这样写
Prelude> filter (\(_, f) -> f < 18.5 || f > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
此函数表示,对于第一个值不重要而第二个值为f
的任何一对,f
必须小于18.5或超过25。
答案 1 :(得分:2)
很高兴看到Ami Tavory's answer解决了您的问题。
但根据这个答案,你评论道:
我尝试使用(!!)的组合访问它,但是没有用。
凭借助教[:D]的洞察力,我猜你在Haskell中将list
与tuple
混淆了。
zip
返回list
tuple
,而(!!)
取list
作为(第一个)参数(因此(!!1)
取一个list
单(!!1)
个参数),因此list
无法应用于zip
返回的tuple
元素,其类型为Prelude> :t zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> :t (!!1)
(!!1) :: [a] -> a
。< / p>
fst
您已经知道snd
和tuple
已应用于Prelude> :t fst
fst :: (a, b) -> a
Prelude> :t snd
snd :: (a, b) -> b
。
cnumber
答案 2 :(得分:1)
使用无点样式的紧凑版本将是
filter ((>18.5).snd) listexpression
这使用函数组合运算符.
,其读作:首先将snd
函数应用于列表中的元组以提取第二个值,然后将比较应用于此值的18.5。
答案 3 :(得分:0)
仅针对各种各样的信息以及一些不会咬人的信息......
在哈斯克尔the list type is an instance of Monad class。因此,像filter
这样的列表操作可以简单地由monadic绑定运算符实现。
*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)]
Monad就是以顺序方式处理所包含的数据。在列表monad中,包含的数据是列表本身的值。因此,绑定运算符可以非常方便地以顺序方式访问monadic值(元组列表)的包含值(元组)。
(>>=) :: Monad m => m a -> (a -> m b) -> m b
monadic绑定运算符的类型签名声明它将monad类型值m a
作为第一个参数(此处为元组列表),并将函数作为第二个参数,它接受纯值并返回monadic value(取一个元组并在列表中返回一个元组或在这种情况下返回一个空列表)。
\t -> if snd t < 25 && snd t > 18.5 then [t] else []
了解列表项如何以及为何一个接一个地应用于提供的函数至关重要。整个列表是一个monadic值,并且绑定运算符访问的包含值将传递给提供的a -> m b
(采用纯值并返回monadic值)类型函数。因此,应用于此函数的所有列表项都变为monadic值(如果条件满足则为[t]
,如果失败则为[]
),然后由bind运算符连接以形成一个monadic返回值(in这种情况下的元组列表满足lambda函数中实现的条件。
此monadic操作也可以使用do
符号
do
t <- [(1,2.3),(3,21.2),(5,17.1),(4,24.4)]
if snd t < 25 && snd t > 18.5 then return t else []
[(3,21.2),(4,24.4)]
当然,这非常类似于列表推导,这实际上是monadic列表操作的语法糖。因此,让我们通过使用列表推导来最终实现它。
*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)]