I need to calculate the minimum of a list but im trying to do it on this Type declaration
Ord a => a ‐> [a] ‐> [a]
which computes the list of those elements of the given list which are smaller than a
given argument (first argument of the function)
mymin :: Ord a => a-> [a] -> [a]
mymin (x:y:xs)
| x > y : mymin(y,xs)
|otherwise
Just use filter. It was made for filtering lists:
mymin :: Ord a => a -> [a] -> [a]
mymin x = filter (< x)
Note: after re-reading the question it seems you may just want to filter the list as mentioned in the other answers, my answer focuses on your initial requirement to find the minimum element of the list. I'll post it anyway, hopefully someone finds it useful.
Your guard syntax is incorrect, but you're almost there with what you've got. Take a look at the section called "Guards, guards!" in learn you a haskell. Guards let you include multiple statements like if a then b, if c then d in a function definition.
You need to include a definition for the otherwise case, you've left it off.
In your code you also should line up the | chars, the white space is significant and changes how the compiler/interpreter runs your program.
I think I can kind of see where you were going with mymin(y,xs) as if you were trying to pass back into your function of type Ord a => a-> [a] -> [a]. However as you've got it that won't work. Your current definition, mymin (x:y:xs) only matches Ord a => [a] -> [a], it's missing a parameter.
If you wanted to pass the smallest value along recursively you'd need to provide a definition like:
mymin :: (Ord a) => a -> [a] -> a
mymin x (y:ys)
Extending your work I've come up with the following. It returns the minimum element of the list but is not defined for an empty list (it will error). It's along the same lines as what you've got but keeps the smallest found item in the first index of the list, instead of passing it along as a separate function argument:
mymin :: Ord a => [a] -> a
mymin zs = head . mymin' $ zs
where mymin' (x:[]) = [x]
mymin' (x:y:xs)
| x > y = mymin' (y:xs)
| otherwise = mymin' (x:xs)
You should probably be reading some basic Haskell guides... Still, two hints to get you going with this problem:
Start with the base case: What's the expected output for an empty list and arbitrary pivot element?
mymin takes two arguments, so the first line of your code should probably be mymin y (x:xs)
Edit: On second thought, have you thought about using filter?
Related
I was wondering if there is a function that lets me split a list at the first occurrence of an element, excluding that element. Basically, suppose:
listT= [1,3,2,5,6,3,2,6]
then I want to define (or not, if it already exists), a function splitAtFirst so that
splitAtFirst 2 listT = [[1,3],[5,6,3,2,6]]
my attempt so far looks like this:
splitAtfirst::(Eq a)=> a->[a]->[[a]]
splitAtfirst _ []=[]
splitAtfirst a (x:xs)
|a==x = [xs]
|otherwise = [x]: splitAtfirst a (xs)
However, I get
>splitAtfirst 2 [1,3,2,5,6,3,2,6]
>[[1],[3],[5,6,3,2,6]]
I know why the problem happens, but so far I haven't been able to find a good solution
I appreciate any help!
Edit: this is an auxiliary function that only will be called after checking that elem is in the list, so dealing with the case when it does not exist it's not really necessary. I appreciate your help
Since dfeuer has already pointed the way towards fixing your implementation, I will just chime in with the ready-made solution:
splitAtFirst :: Eq a => a -> [a] -> ([a], [a])
splitAtFirst x = fmap (drop 1) . break (x ==)
This splitAtFirst implements the second option from the three suggestions in dfeuer's answer. A few notes on each of the components:
(x ==) is a function which tests for equality with x, returning a Bool.
break uses a boolean test (here, (x ==)) to break a list in two, the second list beginning with the first element that passes the test. The two lists are returned as a pair (see dfeuer's answer for the reason why it is so).
drop 1 drops the first element of a list if it is not empty (and leaves it alone if it is empty).
fmap would take quite a bit longer to explain properly, so I will just say that fmap f applied on a pair (such as the result of break) applies the function f to the second element of the pair. In our case, fmap (drop 1) will remove the first element of the second list -- that is, the separator. (To find out more about fmap, search for the keyword "functor", or just try using it on a list or a Maybe-value and see what happens.)
You have committed to the wrong result type, which is preventing the type checker from helping you as much as it could. You say you want
splitAtFirst 2 listT = [[1,3],[5,6,3,2,6]]
This pins you to
splitAtfirst::(Eq a)=> a->[a]->[[a]]
which allows the list to be split into arbitrarily many lists.
But in fact you want to split the list into two. One point you don't address in your question is what you want the result to be if I ask something like splitAtFirst 2 [1,3], where the element is not found. There are three options that seem reasonable:
splitAtFirst :: Eq a => a -> [a] -> Maybe ([a],[a])
-- splitAtFirst 2 [1,3] = Nothing
splitAtFirst :: Eq a => a -> [a] -> ([a],[a])
-- splitAtFirst 2 [1,3] = ([1,3],[])
splitAtFirst :: Eq a => a -> [a] -> ([a], Maybe [a])
-- splitAtFirst 2 [1,3] = ([1,3],Nothing)
Note that I did not suggest
-- splitAtFirst 2 [1,3] = ([], [1,3])
The reason has to do with laziness and efficiency—can you figure out why? The first Maybe version also has this potential problem, but it makes up for it by being more useful.
Once you commit to one of these options, you will likely find it easier to get the implementation right.
Assume the following (non-functioning) code, that takes a predicate such as (==2) and a list of integers, and drops only the last element of the list that satisfies the predicate:
cutLast :: (a -> Bool) -> [Int] -> [Int]
cutLast a [] = []
cutLast pred (as:a)
| (pred) a == False = (cutLast pred as):a
| otherwise = as
This code does not work, so clearly lists cannot be iterated through in reverse like this. How could I implement this idea? I'm not 100% sure if the code is otherwise correct - but hopefully it gets the idea across.
Borrowing heavily from myself: the problem with this sort of question is that you don't know which element to remove until you get to the end of the list. Once we observe this, the most straightforward thing to do is traverse the list one way then back using foldr (the second traversal comes from the fact foldr is not tail-recursive).
The cleanest solution I can think of is to rebuild the list on the way back up, dropping the first element.
cutLast :: Eq a => (a -> Bool) -> [a] -> Either [a] [a]
cutLast f = foldr go (Left [])
where
go x (Right xs) = Right (x:xs)
go x (Left xs) | f x = Right xs
| otherwise = Left (x:xs)
The return type is Either to differentiate between not found anything to drop from the list (Left), and having encountered and dropped the last satisfying element from the list (Right). Of course, if you don't care about whether you dropped or didn't drop an element, you can drop that information:
cutLast' f = either id id . cutLast f
Following the discussion of speed in the comments, I tried swapping out Either [a] [a] for (Bool,[a]). Without any further tweaking, this is (as #dfeuer predicted) consistently a bit slower (on the order of 10%).
Using irrefutable patterns on the tuple, we can indeed avoid forcing the whole output (as per #chi's suggestion), which makes this much faster for lazily querying the output. This is the code for that:
cutLast' :: Eq a => (a -> Bool) -> [a] -> (Bool,[a])
cutLast' f = foldr go (False,[])
where
go x ~(b,xs) | not (f x) = (b,x:xs)
| not b = (False,x:xs)
| otherwise = (True,xs)
However, this is 2 to 3 times slower than either of the other two versions (that don't use irrefutable patterns) when forced to normal form.
One simple (but less efficient) solution is to implement cutFirst in a similar fashion to filter, then reverse the input to and output from that function.
cutLast pred = reverse . cutFirst . reverse
where cutFirst [] = []
cutFirst (x:xs) | pred x = xs
| otherwise = x : cutFirst xs
This is my second day learning Haskell and I am stuck terribly by a problem.
I tried to solve the eighth problem in 99 Haskell questions
The problem is to write a function called "compress" which works like this:
>compress "aaaabbbbccccddddd"
"abcd"
>compress [1,1,1,1,2,3,4,4,4,4]
[1,2,3,4]
and here's what I wrote:
compress :: (Eq a) => [a] -> [a]
compress [] = []
compress x = filter ( (head x) `notElem` ( compress $ tail x ) ) x
The compiler said:
Couldn't match expected type a -> Bool' with actual type Bool'
In compress, I tried to recursively pick up new elements from end to head. (like backtracking maybe??)
Is my algorithm wrong?
Is there alternative way to implement the algorithm in a more readable way?
(Like: where to put parentheses? or $ )
Can someone kindly help me with it?
Thanks a lot.
Thanks to Lubomir's help, I corrected my code by :
compress'(x:xs) = x : compress' (dropWhile (== x) xs)
and it works!
And thanks everyone, I feel spoiled! You guys are so kind!
I'll keep on learning Haskell!
Is there alternative way to implement the algorithm in a more readable
way?
Yes.
import Data.List
compress :: Eq a => [a] -> [a]
compress = map head . group
map head . group is basically \xs -> map head (group xs). group xs will create a list of lists were all equal consecutive elements are grouped together in a list. map head will then take the heads of these lists discarding the rest as required.
The algorithm is basically fine, but it does not typecheck. The first argument to filter should be a function of type a -> Bool – for an element of the list it should tell you whether or not to throw it out. What you have is a single Bool value.
The second part of the function may be better implemented with a different pattern. This would allow you to drop the head and tail functions.
compress [] = []
compress (x:xs) = x : compress (filter (/= x) xs)
This pattern binds x to the first element of the list and xs is the tail of the list. The function should include x in the result and recursively call itself on filtered xs (with x removed from it).
EDIT: this function does not do what the problem requests. Only consecutive duplicates should be eliminated. This can be fixed by using dropWhile instead of filter and slightly modifying the predicate function.
Check the signature of filter:
Prelude> :t filter
filter :: (a -> Bool) -> [a] -> [a]
Note that the first argument must be a function. Now check the type of your expression within the paranthesis.
Prelude> :t notElem
notElem :: Eq a => a -> [a] -> Bool
Thus, notElem a b will return a value of type Bool.
Note: I think you might have misunderstood the problem statement. What is the expected output for aaabbbaaa?
I would argue it should be aba, as the problem is stated as
Eliminate consecutive duplicates of list elements.
(emphasize mine).
I got this function:
foo [] = []
foo (x:xs) = foo us ++ foo ys
where us = filter (<=x) xs
ys = filter (>=x) xs
type of this function is Ord a => [a] -> [b] .
I don't understand why the output type is [b] and not [a]. I think it should be [a] since the elements of the output list will be part of the elements of the input list.
I am using Hugs, but I don't think it changes anything.
The type Ord a => [a] -> [b] is internally consistent, though!
The problem is that you never actually add any elements from the input list to the output list. You need a base case; something like foo [x] = [x]. As it stands, you never actually say that any elements from the input list get added to the output list; the result of this function will always be [], which can have type [b] regardless of input.
If you're trying to implement something like Quicksort here, though, there are two logical problems in your implementation:
x, the pivot, doesn't get added to the output list.
Any values in the list that are equal to x other than x itself will be added twice, once from us and once from ys.
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.