I want to shift a list by n elements to the left. Why do I get an error if I want to change the order from (x:xs) to (xs:x)?
shift n list#(x:xs)
| n == 0 = list
| otherwise = shift (n-1) (xs:x) -- (xs:x) error
Occurs check: cannot construct the infinite type: a ~ [a]
I don't know how to interpret this error. Maybe someone of you can help me.
Thank you very much.
EDIT: As it was already mentioned, the correct term to use is rotate and not shift
Why do I get an error if I want to change the order from (x:xs) to (xs:x)?
Because the types do not match. The type of (:) is (:) :: a -> [a] -> [a]. It thus expects an element x (type a) and a list with the rest of the elements (type [a]). You can not just use (:) in the opposite way.
You can use the (++) :: [a] -> [a] -> [a] to concatenate two lists together. We can thus rotate to the left by dropping n elements from the list and concatenating this with the first n elements of the list to this.
rotateL :: Int -> [a] -> [a]
rotateL 0 list = list
rotateL n list | n < 0 = error "Negative index"
| otherwise = drop n list ++ take n list
or we can, like #YannVernier says, use splitAt :: Int -> [a] -> ([a], [a]):
rotateL :: Int -> [a] -> [a]
rotateL 0 list = list
rotateL n list | n < 0 = error "Negative index"
| otherwise = lb ++ la
where (la, lb) = splitAt n list
or without mentioning the list parameter:
rotateL :: Int -> [a] -> [a]
rotateL 0 = id
rotateL n | n < 0 = error "Negative index"
| otherwise= uncurry (flip (++)) . splitAt n
Note: based on how your attempt, I think you actually want to rotate the list to the left, not shift it, since that would mean that you simply drop the first n elements, and fill it perhaps with some extra value.
Note: in case n is larger than the length of the list, then the rotateL will act as an identity function. That might not be the desired behavior. I leave it as an exercise to fix this edge-case.
It's not the names that define the types, but the positions in a function call, or type declarations. If we check the type of :, we see that the second argument is a list:
Prelude> :t (:)
(:) :: a -> [a] -> [a]
So pattern matching on this constructor will always give you the head and tail, not the init and last. Thus, using both x:xs and xs:x, you've declared that a and [a] are the same type, and the compiler balks. You could perform the append using e.g. xs ++ [x].
Data.Sequence has a type that does support both head and last patterns in the operators :<| and |>:.
In general, (singly linked) lists only make the head element efficiently accessible; operations like appending or even checking lengths are costly. When all you need is a stream or stack, they're great, but a long distance reordering operation like the rotation is better handled by a rope or circular buffer type. Either is available in Haskell, in e.g. container's Seq or ring-buffer's RingBuffer. Data.ByteString.Lazy and Data.Text.Lazy are also rope types.
Related
What is the difference between this two, in terms of evaluation?
Why this "obeys" (how to say?) non-strictness
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter _ [] = []
recFilter p (h:tl) = if (p h)
then h : recFilter p tl
else recFilter p tl
while this doesn't?
recFilter :: (a -> Bool) -> [a] -> Int -> [a]
recFilter _ xs 0 = xs
recFilter p (h:tl) len
| p(h) = recFilter p (tl ++ [h]) (len-1)
| otherwise = recFilter p tl (len-1)
Is it possible to write a tail-recursive function non-strictly?
To be honest I also don't understand the call stack of the first example, because I can't see where that h: goes. Is there a way to see this in ghci?
The non-tail recursive function roughly consumes a portion of the input (the first element) to produce a portion of the output (well, if it's not filtered out at least). Then recursion handles the next portion of the input, and so on.
Your tail recursive function will recurse until len becomes zero, and only at that point it will output the whole result.
Consider this pseudocode:
def rec1(p,xs):
case xs:
[] -> []
(y:ys) -> if p(y): print y
rec1(p,ys)
and compare it with this accumulator-based variant. I'm not using len since I use a separate accumulator argument, which I assume to be initially empty.
def rec2(p,xs,acc):
case xs:
[] -> print acc
(y:ys) -> if p(y):
rec2(p,ys,acc++[y])
else:
rec2(p,ys,acc)
rec1 prints before recursing: it does not need to inspect the whole input list to start printing its output. It works in a "steraming" fashion, in a sense. Instead, rec2 will only start to print at the very end, after the input list was completely scanned.
In your Haskell code there are no prints, of course, but you can thing of returning x : function call as "printing x", since x is made available to the caller of our function before function call is actually made. (Well, to be pedantic this depends on how the caller will consume the output list, but I'll neglect this.)
Hence the non-tail recursive code can also work on infinite lists. Even on finite inputs, performance is improved: if we call head (rec1 p xs), we only evaluate xs until the first non-discarded element. By contrast head (rec2 p xs) would fully filter the whole list xs, even we don't need that.
The second implementation does not make much sense: a variable named len will not contain the length of the list. You thus need to pass this, for infinite lists, this would not work, since there is no length at all.
You likely want to produce something like:
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter p = go []
where go ys [] = ys -- (1)
go ys (x:xs) | p x = go (ys ++ [x]) xs
| otherwise = go ys xs
where we thus have an accumulator to which we append the items in the list, and then eventually return the accumulator.
The problem with the second approach is that as long as the accumulator is not returned, Haskell will need to keep recursing until at least we reach weak head normal form (WHNF). This means that if we pattern match the result with [] or (_:_), we will need at least have to recurse until case one, since the other cases only produce a new expression, and it will thus not yield a data constructor on which we can pattern match.
This in contrast to the first filter where if we pattern match on [] or (_:_) it is sufficient to stop at the first case (1), or the third case 93) where the expression produces an object with a list data constructor. Only if we require extra elements to pattern match, for example (_:_:_), it will require to evaluate the recFilter p tl in case (2) of the first implementation:
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter _ [] = [] -- (1)
recFilter p (h:tl) = if (p h)
then h : recFilter p tl -- (2)
else recFilter p tl
For more information, see the Laziness section of the Wikibook on Haskell that describes how laziness works with thunks.
I am new to Haskell and I'm attempting a task in which the result should be the sum of the last two integers in a string.
I completely understand the overall addition part however it is the manipulation of the string recursively that I'm struggling with. To attempt the task I first 'flipped' the string with the last integer becoming the first for said string to be split after the nth term, in this case 2.
For example, with the given string 1,2,3,4,5,6,7. The result would be 13 as in 6+7=13.
sum' :: [a] -> [a]
sum' = foldl (\acc x -> x : acc) []
sum' :: [a] -> [a]
sum' [] = []
sum' xs = let h = splitAt 1 xs in h
sum' :: (Num a) => [a] -> a
sum' [] = 0
sum' (xs:x) = xs + sum' (x)
main :: IO()
main = do
print(sum'[1,2,3,4,5,6,7])
It is currently very messy and extremely inefficient (not to mention broken). Any help on the functions of haskell which will help me is greatly appreciated.
Working with the ends of lists is hard. My suggestion would be to reverse the list and take 2 elements off the front.
let a:b:_ = reverse [1,2,3,4,5,6,7] in a + b
By the way what you have here is not a String but a List of Int. While Strings are always lists in Haskell, not all Lists are Strings
You should recurse until only two elements are left in the list. So you implement two clauses for the normal behavior, and like some extra ones for the "corner cases".
The base case (1) is a list of two elements in which you need to sum up the elements; the recursive case (2) deals with a list with three or more elements, and recurses on the tail of the list:
sumlast2 :: Num a => [a] -> a
sumlast2 [x1, x2] = … -- (1)
sumlast2 (_:xs#(_:_:_)) = … -- (2)
-- … extra clauses for corner cases …
where you still need to fill in the … parts. In the second clause (2), xs is thus tail of the list: a list with all elements except the first one. You thus will need to define sumlast2 with three or more elements in terms of sumlast2.
my function append takes a list of lists [[a], [b,c], [d,e]] and returns a single list [a,b,c,d,e].
I wrote this in a file so i didn't have to use "let" but i still get parse error on input '='. can anyone help?
thanks
append :: [[a]] -> [a]
append [[a]] = [ a | len = length a, n = 1, head a ++ (a !! n) , n < len]
You need let for len and n:
append [[a]] = [a | let len = length a, let n = 1, head a ++ (a !! n), n < len]
But this won't solve all of your problems, once the lets are added it doesn't typecheck, and [[a]] is probably not the pattern you want to use here. The pattern [[a]] will only match a list like [[1]], it won't match [], or [[1, 2]], or [[1], [2]].
You also have another problem that head a ++ (a !! n) should be an expression that returns a Bool, but in this case it's returning a list. Any "naked" expressions on the right side of the | in a list comprehension must evaluate to a Bool value.
If you're wanting to flatten a list of lists, I would suggest looking at the built-in concat function, which is actually defined using foldr. Folds can be tricky to learn, though, so I'll show an alternate definition using explicit recursion:
myconcat :: [[a]] -> [a]
myconcat [] = []
myconcat (x:xs) = x ++ myconcat xs
This is equivalent to the foldr definition, but hopefully it can be more instructive to how to solve this sort of problem.
You still need to use let to define local variables inside a list comprehension regardless of whether or not the code is in a file. The code being in a file only makes a difference for top-level definitions. Local definitions stay the same.
So the syntactically correct version of your code would be:
append :: [[a]] -> [a]
append [[a]] = [ a | let len = length a, let n = 1, head a ++ (a !! n) , n < len]
-- ^^^ ^^^
isTogether' :: String -> Bool
isTogether' (x:xs) = isTogether (head xs) (head (tail xs))
For the above code, I want to go through every character in the string. I am not allowed to use recursion.
isTogether' (x:xs) = isTogether (head xs) (head (tail xs))
If I've got it right, you are interested in getting consequential char pairs from some string. So, for example, for abcd you need to test (a,b), (b,c), (c,d) with some (Char,Char) -> Bool or Char -> Char -> Bool function.
Zip could be helpful here:
> let x = "abcd"
> let pairs = zip x (tail x)
it :: [(Char, Char)]
And for some f :: Char -> Char -> Bool function we can get uncurry f :: (Char, Char) -> Bool.
And then it's easy to get [Bool] value of results with map (uncurry f) pairs :: [Bool].
In Haskell, a String is just a list of characters ([Char]). Thus, all of the normal higher-order list functions like map work on strings. So you can use whichever higher-order function is most applicable to your problem.
Note that these functions themselves are defined recursively; in fact, there is no way to go through the entire list in Haskell without either recursing explicitly or using a function that directly or indirectly recurses.
To do this without recursion, you will need to use a higher order function or a list comprehension. I don't understand what you're trying to accomplish so I can only give generic advice. You probably will want one of these:
map :: (a -> b) -> [a] -> [b]
Map converts a list of one type into another. Using map lets you perform the same action on every element of the list, given a function that operates on the kinds of things you have in the list.
filter :: (a -> Bool) -> [a] -> [a]
Filter takes a list and a predicate, and gives you a new list with only the elements that satisfy the predicate. Just with these two tools, you can do some pretty interesting things:
import Data.Char
map toUpper (filter isLower "A quick test") -- => "QUICKTEST"
Then you have folds of various sorts. A fold is really a generic higher order function for doing recursion on some type, so using it takes a bit of getting used to, but you can accomplish pretty much any recursive function on a list with a fold instead. The basic type of foldr looks like this:
foldr :: (a -> b -> b) -> b -> [a] -> b
It takes three arguments: an inductive step, a base case and a value you want to fold. Or, in less mathematical terms, you could think of it as taking an initial state, a function to take the next item and the previous state to produce the next state, and the list of values. It then returns the final state it arrived at. You can do some pretty surprising things with fold, but let's say you want to detect if a list has a run of two or more of the same item. This would be hard to express with map and filter (impossible?), but it's easy with recursion:
hasTwins :: (Eq a) => [a] -> Bool
hasTwins (x:y:xs) | x == y = True
hasTwins (x:y:xs) | otherwise = hasTwins (y:xs)
hasTwins _ = False
Well, you can express this with a fold like so:
hasTwins :: (Eq a) => [a] -> Bool
hasTwins (x:xs) = snd $ foldr step (x, False) xs
where
step x (prev, seenTwins) = (x, prev == x || seenTwins)
So my "state" in this fold is the previous value and whether we've already seen a pair of identical values. The function has no explicit recursion, but my step function passes the current x value along to the next invocation through the state as the previous value. But you don't have to be happy with the last state you have; this function takes the second value out of the state and returns that as the overall return value—which is the boolean whether or not we've seen two identical values next to each other.
The question is to compute the mode (the value that occurs most frequently) of a sorted list of integers.
[1,1,1,1,2,2,3,3] -> 1
[2,2,3,3,3,3,4,4,8,8,8,8] -> 3 or 8
[3,3,3,3,4,4,5,5,6,6] -> 3
Just use the Prelude library.
Are the functions filter, map, foldr in Prelude library?
Starting from the beginning.
You want to make a pass through a sequence and get the maximum frequency of an integer.
This sounds like a job for fold, as fold goes through a sequence aggregating a value along the way before giving you a final result.
foldl :: (a -> b -> a) -> a -> [b] -> a
The type of foldl is shown above. We can fill in some of that already (I find that helps me work out what types I need)
foldl :: (a -> Int -> a) -> a -> [Int] -> a
We need to fold something through that to get the value. We have to keep track of the current run and the current count
data BestRun = BestRun {
currentNum :: Int,
occurrences :: Int,
bestNum :: Int,
bestOccurrences :: Int
}
So now we can fill in a bit more:
foldl :: (BestRun -> Int -> BestRun) -> BestRun -> [Int] -> BestRun
So we want a function that does the aggregation
f :: BestRun -> Int -> BestRun
f (BestRun current occ best bestOcc) x
| x == current = (BestRun current (occ + 1) best bestOcc) -- continuing current sequence
| occ > bestOcc = (BestRun x 1 current occ) -- a new best sequence
| otherwise = (BestRun x 1 best bestOcc) -- new sequence
So now we can write the function using foldl as
bestRun :: [Int] -> Int
bestRun xs = bestNum (foldl f (BestRun 0 0 0 0) xs)
Are the functions filter, map, foldr in Prelude library?
Stop...Hoogle time!
Did you know Hoogle tells you which module a function is from? Hoolging map results in this information on the search page:
map :: (a -> b) -> [a] -> [b]
base Prelude, base Data.List
This means map is defined both in Prelude and in Data.List. You can hoogle the other functions and likewise see that they are indeed in Prelude.
You can also look at Haskell 2010 > Standard Prelude or the Prelude hackage docs.
So we are allowed to map, filter, and foldr, as well as anything else in Prelude. That's good. Let's start with Landei's idea, to turn the list into a list of lists.
groupSorted :: [a] -> [[a]]
groupSorted = undefined
-- groupSorted [1,1,2,2,3,3] ==> [[1,1],[2,2],[3,3]]
How are we supposed to implement groupSorted? Well, I dunno. Let's think about that later. Pretend that we've implemented it. How would we use it to get the correct solution? I'm assuming it is OK to choose just one correct solution, in the event that there is more than one (as in your second example).
mode :: [a] -> a
mode xs = doSomething (groupSorted xs)
where doSomething :: [[a]] -> a
doSomething = undefined
-- doSomething [[1],[2],[3,3]] ==> 3
-- mode [1,2,3,3] ==> 3
We need to do something after we use groupSorted on the list. But what? Well...we should find the longest list in the list of lists. Right? That would tell us which element appears the most in the original list. Then, once we find the longest sublist, we want to return the element inside it.
chooseLongest :: [[a]] -> a
chooseLongest xs = head $ chooseBy (\ys -> length ys) xs
where chooseBy :: ([a] -> b) -> [[a]] -> a
chooseBy f zs = undefined
-- chooseBy length [[1],[2],[3,3]] ==> [3,3]
-- chooseLongest [[1],[2],[3,3]] ==> 3
chooseLongest is the doSomething from before. The idea is that we want to choose the best list in the list of lists xs, and then take one of its elements (its head does just fine). I defined this by creating a more general function, chooseBy, which uses a function (in this case, we use the length function) to determine which choice is best.
Now we're at the "hard" part. Folds. chooseBy and groupSorted are both folds. I'll step you through groupSorted, and leave chooseBy up to you.
How to write your own folds
We know groupSorted is a fold, because it consumes the entire list, and produces something entirely new.
groupSorted :: [Int] -> [[Int]]
groupSorted xs = foldr step start xs
where step :: Int -> [[Int]] -> [[Int]]
step = undefined
start :: [[Int]]
start = undefined
We need to choose an initial value, start, and a stepping function step. We know their types because the type of foldr is (a -> b -> b) -> b -> [a] -> b, and in this case, a is Int (because xs is [Int], which lines up with [a]), and the b we want to end up with is [[Int]].
Now remember, the stepping function will inspect the elements of the list, one by one, and use step to fuse them into an accumulator. I will call the currently inspected element v, and the accumulator acc.
step v acc = undefined
Remember, in theory, foldr works its way from right to left. So suppose we have the list [1,2,3,3]. Let's step through the algorithm, starting with the rightmost 3 and working our way left.
step 3 start = [[3]]
Whatever start is, when we combine it with 3 it should end up as [[3]]. We know this because if the original input list to groupSorted were simply [3], then we would want [[3]] as a result. However, it isn't just [3]. Let's pretend now that it's just [3,3]. [[3]] is the new accumulator, and the result we would want is [[3,3]].
step 3 [[3]] = [[3,3]]
What should we do with these inputs? Well, we should tack the 3 onto that inner list. But what about the next step?
step 2 [[3,3]] = [[2],[3,3]]
In this case, we should create a new list with 2 in it.
step 1 [[2],[3,3]] = [[1],[2],[3,3]]
Just like last time, in this case we should create a new list with 1 inside of it.
At this point we have traversed the entire input list, and have our final result. So how do we define step? There appear to be two cases, depending on a comparison between v and acc.
step v acc#((x:xs):xss) | v == x = (v:x:xs) : xss
| otherwise = [v] : acc
In one case, v is the same as the head of the first sublist in acc. In that case we prepend v to that same sublist. But if such is not the case, then we put v in its own list and prepend that to acc. So what should start be? Well, it needs special treatment; let's just use [] and add a special pattern match for it.
step elem [] = [[elem]]
start = []
And there you have it. All you have to do to write your on fold is determine what start and step are, and you're done. With some cleanup and eta reduction:
groupSorted = foldr step []
where step v [] = [[v]]
step v acc#((x:xs):xss)
| v == x = (v:x:xs) : xss
| otherwise = [v] : acc
This may not be the most efficient solution, but it works, and if you later need to optimize, you at least have an idea of how this function works.
I don't want to spoil all the fun, but a group function would be helpful. Unfortunately it is defined in Data.List, so you need to write your own. One possible way would be:
-- corrected version, see comments
grp [] = []
grp (x:xs) = let a = takeWhile (==x) xs
b = dropWhile (==x) xs
in (x : a) : grp b
E.g. grp [1,1,2,2,3,3,3] gives [[1,1],[2,2],[3,3,3]]. I think from there you can find the solution yourself.
I'd try the following:
mostFrequent = snd . foldl1 max . map mark . group
where
mark (a:as) = (1 + length as, a)
mark [] = error "cannot happen" -- because made by group
Note that it works for any finite list that contains orderable elements, not just integers.