Haskell error No instance for (Floating Int) - haskell

This code is to get the distance between 2 points but i got a problem!
UPDATED by #EduardoLeon
rango2 :: Int -> [Int] -> [[Int]] -> [Int]
rango2 a b list = if (verif [(list!!a!!0),(list!!a!!1),(list!!a!!2)] (b)) then [1]
else [0]
verif :: [Int] -> [Int] -> Bool
verif a b = if ((distance a b) > a!!2) then True
else False
difference :: Num a => [a] -> [a] -> [a]
difference xs ys = zipWith (-) xs ys
dotProduct :: Num a => [a] -> [a] -> a
dotProduct xs ys = sum $ zipWith (*) xs ys
distance :: Floating a => [a] -> [a] -> a
distance xs ys = sqrt $ dotProduct zs zs
where
zs = difference xs ys
EDITED: I cant change Int to Float, because im doing operations with lists and now
throw this error!
Proyecto.hs:71:18:
No instance for (Floating Int) arising from a use of `distance'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `(>)', namely `(distance a b)'
In the expression: ((distance a b) > a !! 2)
In the expression:
if ((distance a b) > a !! 2) then True else False

To answer your concrete question: Unlike more conventional languages, Haskell does not automatically cast integers to floats. In fact, the very notion of casting does not exist in Haskell. You need to use the function fromIntegral to convert integers to other numeric types. You could try the following in ghci:
> let x = 5 :: Integer
> sqrt x
<interactive>:3:1:
No instance for (Floating Integer) arising from a use of `sqrt'
In the expression: sqrt x
In an equation for `it': it = sqrt x
> let y = fromIntegral x :: Double
> sqrt y
2.23606797749979
I would also like to make some other suggestions regarding your coding style:
Decompose your functions into smaller functions that do exactly one thing and do it well.
The function (!!) traverses a linked list to find the n-th element. This is an O(n) operation, which is more expensive than necessary if you intend to retrieve multiple elements from the same list. Prefer solutions that avoid traversing the same list more than once.
Here is how I would find the distance between two points:
difference :: Num a => [a] -> [a] -> [a]
difference xs ys = zipWith (-) xs ys
dotProduct :: Num a => [a] -> [a] -> a
dotProduct xs ys = sum $ zipWith (*) xs ys
distance :: Floating a => [a] -> [a] -> a
distance xs ys = sqrt $ dotProduct zs zs
where
zs = difference xs ys

I was searching and i saw that i need to change Int to Float?
Just change the type signature to Float and things will start working:
verif :: [Float] -> [Float] -> Bool
You need to change the type signature of your code to indicate that it works with floating data since sqrt function operates on that. A more generic solution would be this:
verif :: (Floating a, Ord a) => [a] -> [a] -> Bool
verif a b = if (sqrt((((b!!0)-(a!!0))*((b!!0)-(a!!0)))+(((b!!1)-(a!!1))*((b!!1)-(a!!1)))) < a!!3)
then True
else if (sqrt((((b!!0)-(a!!0))*((b!!0)-(a!!0)))+(((b!!1)-(a!!1))*((b!!1)-(a!!1)))) == a!!3)
then True
else False
The use of the !! function isn't encouraged in Haskell. I would suggest you to rewrite the function in a more functional way.

I suggest that you revisit your design. What are the meanings of the lists a and b in verif? It looks like you are finding the distance between two points. You can create a type:
data Point = Point Double Double
and a function
distance :: Point -> Point -> Double
to make your code much more readable.
This should also eliminate doing the same calculation twice by using a where clause or let binding.

Related

Rotate function in Haskell

I want to write a function in Haskell that rotates the list given as the second argument by the number of positions indicated by the first argument. Using pattern matching, implement a recursive function
I have written the following function:
rotate :: Int -> [a] -> [a]
rotate 0 [y]= [y]
rotate x [y]= rotate((x-1) [tail [y] ++ head [y]])
but this function always produces a error. Is there any way to solve it?
The function should do the following when it runs:
rotate 1 "abcdef"
"bcdefa"
[y] does not mean "let y be a list". It means "this argument is a list containing one element called y". You have the right structure, but you don't need the brackets around the y.
rotate :: Int -> [a] -> [a]
rotate 0 y = y
rotate x y = rotate (x-1) (tail y ++ [head y])
TL&DR
rotate :: Int -> [a] -> [a]
rotate = drop <> take
In Haskell the most concise but also a curious way to rotate a list could be using the Semigroup type class instance of the function type (a -> b). Lets check the relevant part of the instance.
instance Semigroup b => Semigroup (a -> b) where
f <> g = \x -> f x <> g x
First things first, <> is in fact the inline version of the mappend function from the Monoid type class.
Then we see, the Semigroup b => constraint in the type signature states that the return type b should also be a member of Semigroup type class. Since we use drop :: Int -> [a] -> [a] and take :: Int -> [a] -> [a] we can quickly notice that b is in fact another function with type signature [a] -> [a] so it is a member of Semigroup type class if and only if it's b, which happens to be [a] is also a member of the Semigroup type class and it is.
instance Semigroup [a] where
(<>) = (++)
So everything holds so far but how does it work?
We can deduce from the type signatures as follows;
(drop :: Int -> ([a] -> [a])) <> (take :: Int -> ([a] -> [a])) is
\n -> (drop n :: [a] -> [a]) <> (take n :: [a] -> [a]) which is
\n -> \xs -> (drop n xs :: [a]) <> (take n xs :: [a]) which is
\n -> \xs -> (drop n xs) ++ (take n xs)
This is basically better than the answers using recursive ++ operator to add the head as a singleton list to the end of the tail since it yields an O(n^2) time complexity.
I think you want something like this:
rotate :: Int -> [a] -> [a]
rotate 0 x = x
rotate times (x:xs) = rotate (times - 1) (xs ++ [x])

Converting a foldl into fold1

I am using the following fold to get the final monotonically decreasing sequence of a list.
foldl (\acc x -> if x<=(last acc) then acc ++ [x] else [x]) [(-1)] a
So [9,5,3,6,2,1] would return [6,2,1]
However, with foldl I needed to supply a start for the fold namely [(-1)]. I was trying to turn into to a foldl1 to be able to handle any range of integers as well as any Ord a like so:
foldl1 (\acc x -> if x<=(last acc) then acc ++ [x] else [x]) a
But I get there error:
cannot construct infinite type: a ~ [a]
in the second argument of (<=) namely last acc
I was under the impression that foldl1 was basically :
foldl (function) [head a] a
But I guess this isn't so? How would you go about making this fold generic for any Ord type?
I was under the impression that foldl1 was basically :
foldl (function) [head a] a
No, foldl1 is basically:
foldl function (head a) (tail a)
So the initial element is not a list of head a, but head a.
How would you go about making this fold generic for any Ord type?
Well a quick fix is:
foldl (\acc x -> if x<=(last acc) then acc ++ [x] else [x]) [head a] (tail a)
But there are still two problems:
in case a is an empty list, this function will error (while you probably want to return the empty list); and
the code is not terribly efficient since both last and (++) run in O(n).
The first problem can easily be addressed by using pattern matching to prevent that scenario. But for the latter you better would for instance use a reverse approach. Like for instance:
f :: Ord t => [t] -> [t]
f [] = [] -- case when the empty list is given
f a = reverse $ foldl (\acc#(ac:_) x -> if x <= ac then (x:acc) else [x]) [head a] (tail a)
Furthermore personally I am not a huge fan of if-then-else in functional programming, you can for instance define a helper function like:
f :: Ord t => [t] -> [t]
f [] = [] -- case when the empty list is given
f a = reverse $ foldl g [head a] (tail a)
where g acc#(ac:_) x | x <= ac = (x:acc)
| otherwise = [x]
Now reverse runs in O(n) but this is done only once. Furthermore the (:) construction runs in O(1) so all the actions in g run in O(1) (well given the comparison of course works efficient, etc.) making the algorithm itself O(n).
For your sample input it gives:
*Main> f [9,5,3,6,2,1]
[6,2,1]
The type of foldl1 is:
Foldable t => (a -> a -> a) -> t a -> a
Your function argument,
\acc x -> if x<=(last acc) then acc ++ [x] else [x]
has type:
(Ord a) => [a] -> a -> [a]
When Haskell's typechecker tries typechecking your function, it'll try unifying the type a -> a -> a (the type of the first argument of foldl1) with the type [a] -> a -> [a] (the type of your function).
To unify these types would require unifying a with [a], which would lead to the infinite type a ~ [a] ~ [[a]] ~ [[[a]]]... and so on.
The reason this works while using foldl is that the type of foldl is:
Foldable t => (b -> a -> b) -> b -> t a -> b
So [a] gets unified with b and a gets unified with the other a, leading to no problem at all.
foldl1 is limited in that it can only take functions which deal with only one type, or, in other terms, the accumulator needs to be the same type as the input list (for instance, when folding a list of Ints, foldl1 can only return an Int, while foldl can use arbitrary accumulators. So you can't do this using foldl1).
With regards to making this generic for all Ord values, one possible solution is to make a new typeclass for values which state their own "least-bound" value, which would then be used by your function. You can't make this function as it is generic on all Ord values because not all Ord values have sequence least bounds you can use.
class LowerBounded a where
lowerBound :: a
instance LowerBounded Int where
lowerBound = -1
finalDecreasingSequence :: (Ord a, LowerBounded a) => [a] -> [a]
finalDecreasingSequence = foldl buildSequence lowerBound
where buildSequence acc x
| x <= (last acc) = acc ++ [x]
| otherwise = [x]
You might also want to read a bit about how Haskell does its type inference, as it helps a lot in figuring out errors like the one you got.

How to pattern match the end of a list?

Say I wanted to remove all zeros at the end of a list:
removeEndingZeros :: (Num a, Eq a) => [a] -> [a]
removeEndingZeros (xs ++ [0]) = removeEndingZeros xs
removeEndingZeros xs = xs
This does not work because of the (++) operator in the argument. How can I determine the end of a list through pattern-matching?
There is a function in Data.List to do this:
dropWhileEnd :: (a -> Bool) -> [a] -> [a]
dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []
So you can drop the trailing zeros with
dropWhileEnd (== 0)
Another, very similar, function can be implemented like this:
dropWhileEnd2 :: (a -> Bool) -> [a] -> [a]
dropWhileEnd2 p = foldr (\x xs -> if null xs && p x then [] else x : xs) []
dropWhileEnd2 p has exactly the same semantics as reverse . dropWhile p . reverse, but can reasonably be expected to be faster by a constant factor. dropWhileEnd has different, non-comparable strictness properties than the others (it's stricter in some ways and less strict in others).
Can you figure out circumstances under which each can be expected to be faster?

Is there any function in Haskell that applies a two argument function to two lists, element by element?

I just wanted to multiply two lists element by element, so I'd pass (*) as the first argument to that function:
apply :: Num a => (a -> a -> a) -> [a] -> [a] -> [a]
apply f xs ys = [f (xs !! i) (ys !! i) | i <- [0..(length xs - 1)]]
I may be asking a silly question, but I actually googled a lot for it and just couldn't find. Thank you, guys!
> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
> zipWith (*) [1,2,3] [4,5,6]
[4,10,18]
It's the eighth result provided by Hoogle when queried with your type
(a -> a -> a) -> [a] -> [a] -> [a]
Moreover, when you need to implement your own function, use list !! index only as a last resort, since it usually leads to a bad performance, having a cost of O(index). Similarly, length should be used only when necessary, since it needs to scan the whole list.
In the zipWith case, you can avoid both and proceed recursively in a natural way: it is roughly implemented as
zipWith _ [] _ = []
zipWith _ _ [] = []
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
Note that this will only recurse as much as needed to reach the end of the shortest list. The remaining part of the longer list will be discarded.

Haskell - sum of cubes of a list

I have to write a function that sums the cubes of a list of numbers.
This is my code so far:
cube' :: (Num a) => a -> a
cube' x = x*x*x
mySum :: (Num a) => [a] -> a
mySum [] = []
mySum xs = foldr (\acc x -> acc + cube'(x)) 0 xs
The problem is that when I run it I get the following error:
No instance for (Num[t0]) arising from a use of 'it'
In a stmt of an interactive GHCI command: print it
You're definitely on the right track. As bhelkir points out in a comment, the first clause of the definition is wrong and unnecessary. The other problem is that you have the argument order wrong for the lambda.

Resources