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.
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