Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 筛选两个列表中较大的元素_List_Haskell_Filter - Fatal编程技术网

List 筛选两个列表中较大的元素

List 筛选两个列表中较大的元素,list,haskell,filter,List,Haskell,Filter,我试图写一个Haskell程序,它输出一个素数列表,但只输出那些平方大于前一个素数和后一个素数乘积的素数。例如,给定 primes = [2, 3, 5, 7, 11, 13, 17] -- keep 5 since 5² > 3*7 -- keep 11 since 11² > 7*13 我的计划是创建正方形和相邻乘积的列表,然后使用过滤器只输出素数列表中正方形大于相邻乘积的元素。 这就是我目前所拥有的 products :: [Int] products = zipWith

我试图写一个Haskell程序,它输出一个素数列表,但只输出那些平方大于前一个素数和后一个素数乘积的素数。例如,给定

primes = [2, 3, 5, 7, 11, 13, 17]
-- keep  5 since  5² > 3*7
-- keep 11 since 11² > 7*13
我的计划是创建正方形和相邻乘积的列表,然后使用过滤器只输出素数列表中正方形大于相邻乘积的元素。 这就是我目前所拥有的

products :: [Int]
products = zipWith (*) primes (drop 2 primes)

squares :: [Int]
squares = zipWith (*) (drop 1 primes) (drop 1 primes)

goodPrimes :: [Int]
goodPrimes = filter (\products, squares -> squares > products) (drop 1 primes)

除了
goodPrimes
功能外,所有功能都正常工作。
我希望一切都很清楚,有人能帮助我。

您的
goodPrimes
lambda(参数之间的逗号)中有语法错误

我们还需要将产品、正方形和素数列表的元素配对(使用
zip3

primes::[Int]
素数=[2,3,5,7,11,13,17]
正方形::[Int]
正方形=zipWith(*)(尾部素数)(尾部素数)
产品::[Int]
产品=带(*)素数的ZIP(下降2个素数)
goodPrimes::[Int]
goodPrimes=fmap(\(prime,\,\)->prime)
$filter(\(素数,prod,square)->square>prod)
$zip3(尾部素数)产品
我们可以内联平方的计算,使
goodPrimes
更干净,然后我们可以删除
squares

goodPrimes::[Int]
goodPrimes=fmap-fst
$filter(\(prime,prod)->prime*prime>prod)
$zip(尾部底漆)产品

您可以进一步使用
zip3
获取包含所有三个相关值的元组;然后一个简单的列表理解将给你最终的结果

> zip3 <*> tail <*> tail.tail $ primes
[(2,3,5),(3,5,7),(5,7,11),(7,11,13),(11,13,17)]
> [ y | (x, y, z) <- zip3 <*> tail <*> tail.tail $ primes, y*y > x*z]
[5,11]
>zip3 tail.tail$primes
[(2,3,5),(3,5,7),(5,7,11),(7,11,13),(11,13,17)]
>[y |(x,y,z)x*z]
[5,11]

zip tail$primes
是一个很好的生成相邻对列表的习惯用法。我不确定zip3 tail tail.tail$primes是否也很好。明确的形式是zip3素数(尾部素数)(尾部素数))你的方向是正确的,但不是完全正确的。为了继续你的思路,我们可以写

goodPrimes = -- filter (\products, squares -> squares > products) (drop 1 primes)
  map (\ (_,_,p) -> p) $
    filter (\ (product, square, prime) -> square > product ) 
           (zip3 products 
                 squares
                 (drop 1 primes))
将方块、产品和素数一起包装成三份,过滤三份,然后回收素数。这被称为范例,或在远古时代

或者我们可以通过列表理解重新实现
过滤器
,融合所有定义并将结果简化为

goodPrimes2 = 
  [ prime | ((prod, sq), prime) <- products `zip` squares `zip` drop 1 primes
          , sq > prod ]
 =
  [ prime | ((prod, sq), prime) <- 
               zipWith (*) primes (drop 2 primes)
                 `zip` zipWith (*) (drop 1 primes) (drop 1 primes)
                   `zip` drop 1 primes
          , sq > prod ]
 =
  [ p1    | ((p0, p2), p1) <- 
               primes `zip` (drop 2 primes) `zip` drop 1 primes
          , p1*p1 > p0*p2]
 =
  [ p1    | (p0:p1:p2:_) <- iterate tail primes  -- or (tails primes)
          , p1*p1 > p0*p2]

玩弄代码,摇动代码,直到它变得简单明了,这是一件很好的事情。这一顺序可以继续下去

 =
  [ p1    | (p0:p1:p2:_) <- iterate tail primes  -- or (tails primes)
          , p1*p1 > p0*p2]
 =
  concatMap (\ case (p0:p1:p2:_) -> [p1 | p1*p1 > p0*p2] )
            (tails primes)
 =
  tails primes >>= (\ case (p0:p1:p2:_) -> [p1 | p1*p1 > p0*p2] )
但是,最后这些将列表视为“单子”的变体现在可能对您不感兴趣


顺便说一句,渐进式尾部上的映射是公共Lisp中的一个原语,称为,而尾部上的concat映射(在其他语言中称为“flatmapping”)也是原语(因此在Haskell中,
mapcon f=(tails>=>f)

欢迎使用StackOverflow。-请试着问一些具体的问题,比如“为什么我会收到这个特定的错误信息”,而不仅仅是“它不起作用,请有人帮帮我”。我可以马上说,
(\products,squares->…)
是无效的语法。您可以将双参数lambda编写为
(\products squares->…)
,也可以将lambda编写为单元组参数
(\(products,squares)->…)
。你明白区别吗?啊,好的,看起来不错,谢谢。我对Haskell还是很陌生,所以我不知道如何正确使用过滤函数,我明白thanks@MichaWiedenmannOP的问题中没有遗漏
。但是注意到,我在
zip3
版本中添加了一个中间步骤。谢谢,这是一个很好的解决方案,我甚至理解它的工作方式!很高兴听到这个消息,不客气。:)主要的教训是,不要害怕玩它,摇动代码,直到它变成简单而美好的东西。
> take 20 primes
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]

> take 10 goodPrimes2
[5,11,17,29,37,41,53,59,67,71]
 =
  [ p1    | (p0:p1:p2:_) <- iterate tail primes  -- or (tails primes)
          , p1*p1 > p0*p2]
 =
  concatMap (\ case (p0:p1:p2:_) -> [p1 | p1*p1 > p0*p2] )
            (tails primes)
 =
  tails primes >>= (\ case (p0:p1:p2:_) -> [p1 | p1*p1 > p0*p2] )
goodPrimes3 = foo primes
   where
   foo = tails >=> (\ case (p0:p1:p2:_) -> [p1 | p1*p1 > p0*p2] )