Haskell 筛选双精度列表并对该结果应用函数

Haskell 筛选双精度列表并对该结果应用函数,haskell,Haskell,[92.0,81.0,81.0,41.0,69.0,95.0,82.0,25.0,92.0,18.0,60.0,68.0,29.0,75.0,87.0,24.0,99.0,93.0,76.0,49.0,36.0] 测试列表在上面 基本上,我得到一个数字列表,我要提取三个一组的数字,然后用一个函数来得到我的答案。我不能使用导入或递归 获取一个双精度列表,将每个连续的三个双精度组视为三角形三条边的长度,使用三角形面积计算其面积;处理列表中的所有双精度后,将所有计算的面积作为双精度列表返回 我打算在这

[92.0,81.0,81.0,41.0,69.0,95.0,82.0,25.0,92.0,18.0,60.0,68.0,29.0,75.0,87.0,24.0,99.0,93.0,76.0,49.0,36.0]

测试列表在上面

基本上,我得到一个数字列表,我要提取三个一组的数字,然后用一个函数来得到我的答案。我不能使用导入或递归

获取一个双精度列表,将每个连续的三个双精度组视为三角形三条边的长度,使用三角形面积计算其面积;处理列表中的所有双精度后,将所有计算的面积作为双精度列表返回

我打算在这个列表上使用过滤器,但不使用双精度。在给定的列表中,三个集合代表三角形面积函数(a,b,c)。然后我需要对这些数字应用三角形面积函数

不知道怎么做

因此给出[92.0,81.0,81.0,41.0,69.0,95.0,82.0,25.0,92.0,18.0,60.0,68.0,29.0,75.0,87.0,24.0,99.0,93.0,76.0,49.0,36.0]

上述列表分解后的区域应为 [3066.91258.5986.4510.91052.01106.7712.6]

这是另一种尝试 但它不起作用

triangle_area :: Double -> Double -> Double -> Double
triangle_area a b c = sqrt (s * (s - a) * (s - b) * (s - c)) where s = (a +     b + c) / 2.0

splitEvery :: Int -> [a] -> [[a]]
splitEvery n = takeWhile (not.null) . map (take n) . iterate (drop n)

triangle_areas :: [Double] -> [Double]
triangle_areas [] = []
triangle_areas (a:b:c:xs) = triangle_area a b c : triangle_areas xs
基本上,我想每3[1..9]进行一次拆分,然后在这些拆分列表上取三角形区域

三角形区域目前运行良好,但我无法使用递归,因此需要返工

工作


非常感谢切普纳您可以使用
地图的定义来获得灵感

map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
map
将其函数应用于一个参数;您希望将函数应用于三个参数

triangle_areas :: [Double] -> [Double]
triangle_areas xs = map3 triangle_area xs
                    where map3 f (s1:s2:s3:rest) = f s1 s2 s3 : map3 f rest
                          -- map3 _ [s1, s2] = ???
                          -- map3 _ [s1] = ???
                          map3 _ [] = []
我将
map3
作为一个分部函数,对于剩余1或2个值的列表,它没有定义


您的
splitEvery
正常;您只需要修改
三角形区域的定义
,这样它就可以接受一个3元素列表作为输入

triangle_area [a,b,c] = sqrt (s * (s - a) * (s - b) * (s - c)) 
                        where s = (a + b + c) / 2.0
现在,您可以将其映射到
splitEvery
的输出上

triangle_areas = map triangle_area . splitEvery 3

以下不是最优雅的,但可以作为灵感(至少在你的例子中是这样):

它的工作原理是将计算出的面积和下一个要计算面积的当前三角形的边累加起来。这是在元组
(r,sides)
中完成的。当我们得到三角形的三条边(2条在列表
边中累积,第三条在参数
x
中累积)时,我们
计算面积并将其添加到结果列表中,否则我们将保留结果列表不变,并将当前边(参数
x
)添加到

我认为您误解了这个问题。给定
[1..9]
,这三个三角形有边
[1,2,3]
[4,5,6]
[7,8,9]
。我想你是对的,我会修改我的错误并添加一些代码。看起来map3是递归的吗?我不能使用递归。我已经用一个工作代码更新了我的尝试,但我也使用了递归。如果您能帮助我在不使用递归的情况下获得相同的输出,我将非常感激。在函数式编程语言中,“无递归”是一个奇怪的要求。说你只能使用前奏曲中的高阶函数是正确的吗?有没有办法将这篇文章标记为“已回答”并让你的文章成为你的目标?
triangle_area [a,b,c] = sqrt (s * (s - a) * (s - b) * (s - c)) 
                        where s = (a + b + c) / 2.0
triangle_areas = map triangle_area . splitEvery 3

    triangle_areas :: [Double] -> [Double]
    triangle_areas =
      fst .
      foldl (\(r, sides) x ->
              if length sides == 2
              then (r ++ [triangle_area (sides !! 0) (sides !! 1) x], [])
              else (r, sides ++ [x]))
      ([],[])