haskell perimeter lists

0

Could you help me do this?:

perimetro :: (Ord a) => [a] -> [a] -> Float 
perimetro [] [] = 0.0
perimetro xt xs = 

I do not know how to get the first and last item out of each list at the same time to be able to operate them.

    
asked by Daniel Herrera Gomez 19.09.2017 в 21:23
source

1 answer

0

Please edit the question and change the graphic by text. It will facilitate the subsequent search to who may be interested in the question.

In haskell, the lists have a series of methods offered by the Data.List module, present simply because they are imported in Prelude .

So you have:

  • head and tail to get the first element and the rest
  • init and last to get the first elements and the last

Because of how the lists are constituted as linked lists , it is preferable to use head/tail to init/last for efficiency.

head :: [a] -> a
tail :: [a] -> [a]

init :: [a] -> [a] 
last :: [a] -> a

That said, the best way to create these pairs is by using the zip functions:

zip :: [a] -> [b] -> [(a, b)]
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

For example zip (tail xs) xs would give us a list of tuples: [(x 1 , x 0 ), (x 2 , x 1 ), ..., ( x n , x n-1 )].

With zipWith (-) (tail xs) xs we would do the subtraction in a single step: [(x 1 -x 0 ), (x 2 -x 1 ), ..., (x n -x n-1 )]

But we still need to close the cycle with the tuple (x 0 , x n ). Just add the first element at the end, something like this: zipWith (-) (tail xs ++ [head xs]) xs

The same would be with the list ys , and would be applied again zip to do the summation. Putting things in their place, it would be something like this:

perimetro :: (Floating a) => [a] -> [a] -> a 
perimetro [] [] = 0.0
perimetro xs ys = sum [sqrt (i^2+j^2) | (i,j) <- zip xrs yrs]
    where
      rotl (z:zs) = zs ++ [z]
      xrs = zipWith (-) (rotl xs) xs
      yrs = zipWith (-) (rotl ys) ys
    
answered by 20.09.2017 в 18:55