Rotate function in Haskell - 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])

Related

Replace elements in the list

I need to implement a function that replaces elements in a list -- the
index to replace at is the fst in the tuple, and the snd in the tuple
is what to replace it with. and I am asked to use foldr or map function.
for example:
setElements [(1, 'a'), (-4, 't'), (3, 'b')] "#####" = "#a#b#"
the setElements function doesn't compile:
my code:
setElement :: Int -> a -> [a] -> [a]
setElement n x xs = if ((n < length xs) && n >= 0)
then (take n xs) ++ [x] ++ (drop (n + 1) xs)
else xs
setElements :: [(Int, a)] -> [a] -> [a]
setElements = foldr (\t l-> setElement (fst t) (snd t) l) []
I get:
• Couldn't match type ‘[a]’ with ‘[a] -> [a]’
Expected type: [(Int, a)] -> [a] -> [a]
Actual type: [(Int, a)] -> [a]
• Possible cause: ‘foldr’ is applied to too many arguments
In the expression: foldr (\ t l -> setElement (fst t) (snd t) l) []
In an equation for ‘setElements’:
setElements = foldr (\ t l -> setElement (fst t) (snd t) l) []
• Relevant bindings include
setElements :: [(Int, a)] -> [a] -> [a]
(bound at hw3.hs:79:1)
|
79 | setElements = foldr (\t l-> setElement (fst t) (snd t) l) []
|
How can I fix the error?
Let's look at your function:
setElements :: [(Int, a)] -> [a] -> [a]
setElements = foldr (\t l-> setElement (fst t) (snd t) l) []
and recall the type of foldr:
foldr :: (a -> b -> b) -> b -> [a] -> b
In your use of foldr, you have a as (Int, a) and b as [a]. And you only give it the first 2 arguments. So foldr (\t l-> setElement (fst t) (snd t) l) [] has type [(Int, a)] -> [a] - whereas setElements is supposed to have type [(Int, a)] -> [a] -> [a]. Note how these match exactly with the "actual type" and "expected type" reported by GHC in the error message.
To fix this, I would actually take a step backwards. Folding is the right idea - your setElement function already modifies the original list (its third argument) based on an index and new value, and what you want is to take a list of pairs encoding this data, and keep on applying this function to update the original list repeatedly. (Of course this is Haskell so data is immutable - you're not literally updating it in place, but simply returning a new list each time. But sometimes talking loosely like this is easier.)
That's exactly what a fold is. Let's try to write it out, without trying to be too fancy with a "point-free" approach, but instead fully applying it:
setElements :: [(Int, a)] -> [a] -> [a]
setElements ps as = foldr myFunction as ps
where myFunction = undefined
The undefined here is just a placeholder - it will cause a runtime error if you try to use the function (but won't cause a compilation error), and I've put it there because we need to think about that, the fold function usually being the trickiest part of implementing a fold. But let's check we understand what the other terms are doing: the list we are actually "walking along" is the list of (Int, a) terms that tell us what to insert and where - that's what I've called ps (the p is for "pair"). And because we are starting with the list of as - which I've logically called as here - then that should be the starting accumulator value, which is the second argument to foldr.
So all that remains is the fold function - which takes a pair and a list, and updates the list according to the values in the pair. Well this is the function you're already using:
\t l-> setElement (fst t) (snd t) l
or, rewritten with pattern matching (which I find much more readable, and for this reason I think is preferred by most Haskell developers):
\(i, a) as -> setElement i a as
So, substituting this in, we arrive at the following definition:
setElements :: [(Int, a)] -> [a] -> [a]
setElements ps as = foldr myFunction as ps
where myFunction = \(i, a) as -> setElement i a as
This now will compile and work correctly. But it's always worth taking a step back when you have a working function, and seeing if you can simplify its definition. In fact myFunction can be simplified quite a bit:
\(i, a) as -> setElement i a as
can first be "eta-reduced" to
\(i, a) -> setElement i a
which, using a standard library function, is simply uncurry setElement.
At this stage we clearly don't need a where clause any more (in fact we never did before, but imo it aids readability for any lambda which isn't fairly trivial), and can just write:
setElements :: [(Int, a)] -> [a] -> [a]
setElements ps as = foldr (uncurry setElement) as ps
In fact, while I wouldn't necessarily recommend it, if we're playing code golf you can even go a step further and just write:
setElements = flip . foldr . uncurry $ setElement
I personally think the ability to be able to express relatively complex functions in a concise way, as above, is definitely part of the allure of Haskell. But, rather than try to write something like this straight away, in my opinion it's always best to start with something very concrete showing how you want to transform your data - and, only after getting that working, look for a more concise representation if you want to.

How can I use map on the resulting list of another function?

mean :: (Real a, Fractional b) => [a] -> b
mean xs = (realToFrac(sum xs) / realToFrac(length xs))
sqDiff1 :: (Fractional b, Real b) => [b] -> [b]
sqDiff1 xs = map(subtract (mean xs))xs
sqDiff2 :: Num b => (t -> [b]) -> t -> [b]
sqDiff2 sqDiff2 xs = map(^ 2)(sqDiff2 xs)
sqDiff1 subtracts the mean of a list from each of the elements.
Basically what I'm trying to do is square the elements of sqDiff1.
How can I achieve this?
If you want to square the differences from only that function, you don't need a function parameter:
sqDiff2 :: Real b => [b] -> [b]
sqDiff2 xs = map (^ 2) (sqDiff1 xs)
If you really intended to have a function parameter, pass the one you want to use:
*Main> sqDiff2 sqDiff1 [1,2,3,4,5,6]
[6.25,2.25,0.25,0.25,2.25,6.25]

Basic encryption using higher order functions in Haskell

I'm working on a problem that runs along the lines of basic encryption. I'm trying to create a function called encryptf that
takes a list xs of a's
takes a list ys of a's
returns a function that maps elements of xs to the corresponding elements of ys and maps everything else to itself.
So far it looks like this:
encryptf :: Eq a => [a] -> [a] -> (a -> a)
encryptf xs ys = \f -> head [d | (c,d) <- (zip xs ys)]
Then there's a second function called encryptString that looks like this:
encryptString :: (a -> a) -> [a] -> [a]
encryptString f xs = map f xs
and these functions will be used like this:
encryptString (encryptf "abc" "xyz") "dcba"
and that would return "dzyx"
Now I know that my encryptf function is wrong, because it would change everything to the first element of ys. I'm not sure where to go from here. Any help would be appreciated.
The idea is you search the given character in zipped list, and if it there then return second pair and if not then return the character itself.
encryptf :: Eq a => [a] -> [a] -> (a -> a)
encryptf xs ys =
let ret = zip xs ys in
\f ->
case lookup f ret of
Just c -> c
Nothing -> f
encryptString :: (a -> a) -> [a] -> [a]
encryptString f xs = map f xs
*Main> encryptString (encryptf "abc" "xyz") "dcba"
"dzyx"

Adding predicate to a map function

Completely new to Haskell and learning through Learn Haskell the greater good.
I am looking at the map function
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
is it possible to add a predicate to this? for example, to only map to every other element in the list?
You can code your own version of map to apply f only to even (or odd) positions as follows. (Below indices start from 0)
mapEven :: (a->a) -> [a] -> [a]
mapEven f [] = []
mapEven f (x:xs) = f x : mapOdd f xs
mapOdd :: (a->a) -> [a] -> [a]
mapOdd f [] = []
mapOdd f (x:xs) = x : mapEven f xs
If instead you want to exploit the library functions, you can do something like
mapEven :: (a->a) -> [a] -> [a]
mapEven f = map (\(flag,x) -> if flag then f x else x) . zip (cycle [True,False])
or even
mapEven :: (a->a) -> [a] -> [a]
mapEven f = map (uncurry (\flag -> if flag then f else id)) . zip (cycle [True,False])
If you want to filter using an arbitrary predicate on the index, then:
mapPred :: (Int -> Bool) -> (a->a) -> [a] -> [a]
mapPred p f = map (\(i,x) -> if p i then f x else x) . zip [0..]
A more direct solution can be reached using zipWith (as #amalloy suggests).
mapEven :: (a->a) -> [a] -> [a]
mapEven f = zipWith (\flag x -> if flag then f x else x) (cycle [True,False])
This can be further refined as follows
mapEven :: (a->a) -> [a] -> [a]
mapEven f = zipWith ($) (cycle [f,id])
The "canonical" way to perform filtering based on positions is to zip the sequence with the naturals, so as to append an index to each element:
> zip [1, 1, 2, 3, 5, 8, 13] [0..]
[(1,0),(1,1),(2,2),(3,3),(5,4),(8,5),(13,6)]
This way you can filter the whole thing using the second part of the tuples, and then map a function which discards the indices:
indexedFilterMap p f xs = (map (\(x,_) -> f x)) . (filter (\(_,y) -> p y)) $ (zip xs [0..])
oddFibsPlusOne = indexedFilterMap odd (+1) [1, 1, 2, 3, 5, 8, 13]
To be specific to you question, one might simply put
mapEveryOther f = indexedFilterMap odd f
You can map with a function (a lambda is also possible):
plusIfOdd :: Int -> Int
plusIfOdd a
| odd a = a
| otherwise = a + 100
map plusIfOdd [1..5]
As a first step, write the function for what you want to do to the individual element of the list:
applytoOdd :: Integral a => (a -> a) -> a -> a
applytoOdd f x = if odd x
then (f x)
else x
So applytoOdd function will apply the function f to the element if the element is odd or else return the same element if it is even. Now you can apply map to that like this:
λ> let a = [1,2,3,4,5]
λ> map (applytoOdd (+ 100)) a
[101,2,103,4,105]
Or if you want to add 200 to it, then:
λ> map (applytoOdd (+ 200)) a
[201,2,203,4,205]
Looking on the comments, it seems you want to map based on the index position. You can modify your applytoOdd method appropriately for that:
applytoOdd :: Integral a => (b -> b) -> (a, b) -> b
applytoOdd f (x,y) = if odd x
then (f y)
else y
Here, the type variable a corresponds to the index element. If it's odd you are applying the function to the actual element of the list. And then in ghci:
λ> map (applytoOdd (+ 100)) (zip [1..5] [1..])
[101,2,103,4,105]
λ> map (applytoOdd (+ 200)) (zip [1..5] [1..])
[201,2,203,4,205]
Or use a list comprehension:
mapOdd f x = if odd x then f x else x
[ mapOdd (+100) x | x <- [1,2,3,4,5]]
I'm glad that you're taking the time to learn about Haskell. It's an amazing language. However it does require you to develop a certain mindset. So here's what I do when I face a problem in Haskell. Let's start with your problem statement:
Is it possible to add a predicate to the map function? For example, to only map to every other element in the list?
So you have two questions:
Is it possible to add a predicate to the map function?
How to map to every other element in the list?
So the way people think in Haskell is via type signatures. For example, when an engineer is designing a building she visualizes how the building should look for the top (top view), the front (front view) and the side (side view). Similarly when functional programmers write code they visualize their code in terms of type signatures.
Let's start with what we know (i.e. the type signature of the map function):
map :: (a -> b) -> [a] -> [b]
Now you want to add a predicate to the map function. A predicate is a function of the type a -> Bool. Hence a map function with a predicate will be of the type:
mapP :: (a -> Bool) -> (a -> b) -> [a] -> [b]
However, in your case, you also want to keep the unmapped values. For example mapP odd (+100) [1,2,3,4,5] should result in [101,2,103,4,105] and not [101,103,105]. Hence it follows that the type of the input list should match the type of the output list (i.e. a and b must be of the same type). Hence mapP should be of the type:
mapP :: (a -> Bool) -> (a -> a) -> [a] -> [a]
It's easy to implement a function like this:
map :: (a -> Bool) -> (a -> a) -> [a] -> [a]
mapP p f = map (\x -> if p x then f x else x)
Now to answer your second question (i.e. how to map to every other element in the list). You could use zip and unzip as follows:
snd . unzip . mapP (odd . fst) (fmap (+100)) $ zip [1..] [1,2,3,4,5]
Here's what's happening:
We first zip the index of each element with the element itself. Hence zip [1..] [1,2,3,4,5] results in [(1,1),(2,2),(3,3),(4,4),(5,5)] where the fst value of each pair is the index.
For every odd index element we apply the (+100) function to the element. Hence the resulting list is [(1,101),(2,2),(3,103),(4,4),(5,105)].
We unzip the list resulting in two separate lists ([1,2,3,4,5],[101,2,103,4,105]).
We discard the list of indices and keep the list of mapped results using snd.
We can make this function more general. The type signature of the resulting function would be:
mapI :: ((Int, a) -> Bool) -> (a -> a) -> [a] -> [a]
The definition of the mapI function is simple enough:
mapI :: ((Int, a) -> Bool) -> (a -> a) -> [a] -> [a]
mapI p f = snd . unzip . mapP p (fmap f) . zip [1..]
You can use it as follows:
mapI (odd . fst) (+100) [1,2,3,4,5]
Hope that helps.
Is it possible to add a predicate to this? for example, to only map to every other element in the list?
Yes, but functions should ideally do one relatively simple thing only. If you need to do something more complicated, ideally you should try doing it by composing two or more functions.
I'm not 100% sure I understand your question, so I'll show a few examples. First: if what you mean is that you only want to map in cases where a supplied predicate returns true of the input element, but otherwise just leave it alone, then you can do that by reusing the map function:
mapIfTrue :: (a -> Bool) -> (a -> a) -> [a] -> [a]
mapIfTrue pred f xs = map step xs
where step x | pred x = f x
| otherwise = x
If what you mean is that you want to discard list elements that don't satisfy the predicate, and apply the function to the remaining ones, then you can do that by combining map and filter:
filterMap :: (a -> Bool) -> (a -> b) -> [a] -> [b]
filterMap pred f xs = map f (filter pred xs)
Mapping the function over every other element of the list is different from these two, because it's not a predicate over the elements of the list; it's either a structural transformation of the list of a stateful traversal of it.
Also, I'm not clear whether you mean to discard or keep the elements you're not applying the function to, which would imply different answers. If you're discarding them, then you can do it by just discarding alternate list elements and then mapping the function over the remaining ones:
keepEven :: [a] -> [a]
keepEven xs = step True xs
where step _ [] = []
step True (x:xs) = x : step False xs
step False (_:xs) = step True xs
mapEven :: (a -> b) -> [a] -> [b]
mapEven f xs = map f (keepEven xs)
If you're keeping them, one way you could do it is by tagging each list element with its position, filtering the list to keep only the ones in even positions, discard the tags and then map the function:
-- Note: I'm calling the first element of a list index 0, and thus even.
mapEven :: (a -> a) -> [a] -> [a]
mapEven f xs = map aux (filter evenIndex (zip [0..] xs))
where evenIndex (i, _) = even i
aux (_, x) = f x
As another answer mentioned, zip :: [a] -> [b] -> [(a, b)] combines two lists pairwise by position.
But this is the general philosophy: to do a complex thing, use a combination of general-purpose generic functions. If you're familiar with Unix, it's similar to that.
Another simple way to write the last one. It's longer, but keep in mind that evens, odds and interleave all are generic and reusable:
evens, odds :: [a] -> [a]
evens = alternate True
odds = alternate False
alternate :: Bool -> [a] -> [a]
alternate _ [] = []
alternate True (x:xs) = x : alternate False xs
alternate False (_:xs) = alternate True xs
interleave :: [a] -> [a] -> [a]
interleave [] ys = ys
interleave (x:xs) ys = x : interleave ys xs
mapEven :: (a -> a) -> [a] -> [a]
mapEven f xs = interleave (map f (evens xs)) (odds xs)
You can't use a predicate because predicates operate on list values, not their indices.
I quite like this format for what you're trying to do, since it makes the case handling quite clear for the function:
newMap :: (t -> t) -> [t] -> [t]
newMap f [] = [] -- no items in list
newMap f [x] = [f x] -- one item in list
newMap f (x:y:xs) = (f x) : y : newMap f xs -- 2 or more items in list
For example, running:
newMap (\x -> x + 1) [1,2,3,4]
Yields:
[2,2,4,4]

Haskell error No instance for (Floating Int)

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.

Resources