Related
This is what I have so far:
toStr :: (Num a) => [a] -> String
toStr (x:xs)
| length xs == 0 = []
| length xs > 0 = show x : toStr xs
I keep getting this error:
* Couldn't match type `Char' with `[Char]'
Expected type: [String]
Actual type: String
I don't understand why it is receiving a Char instead of a [Char]. Thanks in advance.
For help, the thing I am trying to do is convert a binary list [1, 0, 0, 1, 1, 0] to a list like this "100110".
Understanding the Problem
toStr :: (Num a) => [a] -> String
toStr (x:xs)
| length xs == 0 = []
| length xs > 0 = show x : toStr xs
^ ^ ^
This is a String | |
| This is a String
This is a function of type String -> [String] -> [String]
So you have:
show x which is a String
toStr xs which is a String
The function : which expects a String and [String].
That disagreement on toStr xs is a String but was expected, by : to be a list of Strings is the crux of the problem. You wanted to concatenate your strings together into a single string (show x ++ toStr xs).
Understanding the Next Problem*
Now you should have a few other issues. First, you have an Num a => a that you try to show. The function show is not part of Num but instead part of the Show class so change Num a => to Show a =>.
Finally, this code doesn't handle the empty list case very well:
toStr (x:xs)
| length xs == 0 = []
Noticing nothing comes after x this code will ignore the last value, x, and return the empty list. It doesn't handle the case where there is no "last element" and all you have is the empty list. To handle that try toStr [] = [].
Putting it Together
toStr :: (Show a) => [a] -> String
toStr [] = []
toStr (x:xs) = show x ++ toStr xs
with a result of:
> toStr [1,0,0,1,1]
"10011"
Idiomatic Code
The above is a fine result but manual primitive recursive functions aren't usually necessary when writing Haskell. Most operations are a type of map or fold over the data. In this case it is a mapping of the show function (notice how it is showing every element) and a fold of the ++ function - also known as string concatenation.
toStr2 xs = foldr (++) "" (map show xs)
-- > toStr2 [1,0,0,1,1]
-- "10011"
Even this can be further simplified. It is so common there exists a special function concatMap:
toStr3 xs = concatMap show xs
Which we can "eta reduce" (remove the outer most arguments of the function definition/application - think in terms of defining a function as another function and not the values it produced):
toStr4 = concatMap show
Alternatively, we could re-gain the original verb-age of fold and map. The concatMap function is just a specific type of fold + map that works over lists. There is a more general foldMap that works with any function that produces a monoid (and lists are one such structure, which means that so are Strings since they are lists of characters):
toStr5 = foldMap show
As mentioned by Sergey, the ':' operator cannot be used, because the expression "show x" returns a string not a single character.
This code below seems to do what you wanted:
toStr :: (Num a, Show a) => [a] -> String
toStr (x:xs)
| null xs = show x -- avoid using length because of cost
| not (null xs) = (show x) ++ (toStr xs)
toStr [] = ""
main = do
let ls1 = [ 13, 17, 19, 23 ]
let st1 = toStr ls1
let st2 = concatMap show ls1 -- as per melpomene's remark
putStrLn $ "st1 = " ++ st1
putStrLn $ "st2 = " ++ st2
As a side remark, Haskell programmers generally avoid to use the length function when they just want to know whether a list is empty or not. Things can get really ugly if you do that, because of our potentially unlimited lazy lists.
This is a homework , it's to removing the adjacent duplicates.
The result should like this removeAdjacentDuplicates [3,1,2,2,2,2,2,4,4,2,2,3] == [3,1,2,4,2,3]
I knew it's not necessary to use head here, but it's not allowed to use rekursion and List-Comprehensions of Form [e | ...]. Only the function in Prelude is permittet, group und so on , which in other packages are also not allowed. map zip filter concat reverse foldr are recommended.
For example , It's not possible to make this:
removeAdjacentDuplicates :: Eq a => [a] -> [a]
removeAdjacentDuplicates (x:xs#(y:_))
| x == y = x:tail (removeAdjacentDuplicates xs)
| otherwise = x:removeAdjacentDuplicates xs
so I try like this
removeAdjacentDuplicates = foldr (\x result -> if ( x == (head result)) then result else (x : result)) []
but when I test it, it throw *** Exception: Prelude.head: empty list' here out
I have tried to add removeAdjacentDuplicates [] = [] before,
But error is like this
Equations for ‘removeAdjacentDuplicates’ have different numbers of arguments
H7-1.hs:24:1-32
H7-1.hs:25:1-105
|
24 | removeAdjacentDuplicates [] = []
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
I don't understand where the problem is, and how can I solve it?
x == head result dies if result is [] -- and result is definitely [] in the first iteration of foldr, so adding a special case for when the input list would not require foldr to do any iterations is fixing exactly the wrong case!
Instead of trying to extract a value from the result list, you could insert x into a list; so consider using the condition
[x] == take 1 result
instead -- it never dies.
As said by #DanielWagner, head :: [a] -> a will raise an error for empty lists. We can solve this by using take :: Int -> [a] -> [a], or by using pattern matching:
removeAdjacentDuplicates :: (Foldable f, Eq a) => f a -> [a]
removeAdjacentDuplicates = foldr f []
where f x ys#(y:_) | x == y = ys
f x ys = (x:ys)
here ys#(y:_) will match given the list is non-empty, with y as head of the list. In that case we thus check if x == y, and if that holds, we return ys. Otherwise we return (x:ys).
In Haskell, how do I implement a function dup that duplicates all elements that are on even positions (0,2,4...) in a list
dup :: [a] -> [a]
dup [] = []
dup (x:xs) = x : x : dup xs
//but only on even index ??
Example of call:
dup [1,5,2,8,4] = [1,1,5,2,2,8,4,4]
Well we can define two functions that perform mutual recursion: dupeven :: [a] -> [a] and dupodd :: [a] -> [a]. dupeven thus will duplicate the first element, and the pass recursively to dupodd. dupodd on the other hand only makes one copy of the head, and then perform recursion on dupeven. Like:
dupeven :: [a] -> [a]
dupeven [] = []
dupeven (x:xs) = x : x : dupodd xs
dupodd :: [a] -> [a]
dupodd [] = []
dupodd (x:xs) = x : dupeven xs
The nice thing is that we get two dupplicate variants. Furthermore both functions are rather simple: they only operate on two different patterns the empty list [] and the "cons" (:).
This thus works as expected, and furthermore we basically have an extra function at (rather) low implementation cost:
Prelude> dupeven [1,5,2,8,4]
[1,1,5,2,2,8,4,4]
Prelude> dupodd [1,5,2,8,4]
[1,5,5,2,8,8,4]
As other answers explain, you can write this function recursively from first principles, but I always think problems like these are interesting puzzles: how can you compose such a function from the existing base library?
First, whenever you want to index a list, you can zip it with a lazily evaluated infinite list:
Prelude> zip [0..] [1,5,2,8,4]
[(0,1),(1,5),(2,2),(3,8),(4,4)]
In this case, though, you don't really need to know the actual index values (0, 1, 2, 3, 4 and so on). Instead, you just need to know how many repetitions of each number you need. You can produce that knowledge by infinitely cycling through 2 and 1:
Prelude> take 10 $ cycle [2,1]
[2,1,2,1,2,1,2,1,2,1]
(The above example uses take 10 to stop evaluation of the list, which, otherwise, continues forever.)
You can zip (cycle [2,1]) with any input list to get a list of tuples:
Prelude> zip (cycle [2,1]) [1,5,2,8,4]
[(2,1),(1,5),(2,2),(1,8),(2,4)]
The first element of the tuple is how many times to repeat the second element.
You can use replicate to repeat any value a number of times, but you'll have to uncurry it to take a single tuple as input:
Prelude> uncurry replicate (2,1)
[1,1]
Prelude> uncurry replicate (1,5)
[5]
Notice that this function always returns a list, so if you do this over a list of tuples, you'll have a list of lists. To immediately flatten such a list, you can therefore use monadic bind to flatten the projection:
Prelude> zip (cycle [2,1]) [1,5,2,8,4] >>= uncurry replicate
[1,1,5,2,2,8,4,4]
You can, if you will, make a function out of it:
dup xs = zip (cycle [2,1]) xs >>= uncurry replicate
This function turns out to be parametrically polymorphic, so while you can use it with lists of integers, you can also use it with lists of characters:
Prelude> dup [1,5,2,8,4]
[1,1,5,2,2,8,4,4]
Prelude> dup "acen"
"aaceen"
You may want to make a mutually recursive set of functions
duplicate, duplicate' :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : x : duplicate' xs
duplicate' [] = []
duplicate' (x:xs) = x : duplicate xs
Or add a simple ADT to determine the next action
data N = O | T
duplicate = duplicate' T
duplicate' _ [] = []
duplicate' T (x:xs) = x : x : duplicate' O xs
duplicate' O (x:xs) = x : duplicate' T xs
But in all honesty, the best way of doing it is what #Simon_Shine suggested,
duplicate [] = []
duplicate (x:y:xs) = x : x : y : duplicate xs
duplicate (x:xs) = x : x : xs -- Here x is an even index and xs is an empty list
I got a Haskell function that is defined using pattern matching but i'm not really understand why is it looks like the way it is.
safeTail (x : xs) = xs
I'm not really understand specifically at the (x : xs), what does it mean ?
Consider a similar definition for a list data type.
data List a = Empty | Cons a (List a) -- (1)
There are two constructors: one to create an empty list, and another to create a list given a value and another list.
Pattern matching works by matching a value against the constructor used to create it.
safeTail (Cons x xs) = xs -- (2)
That is, if safeTail is applied to a value defined using the Cons constructor, then the return value is the second argument to Cons.
In real code, both the type constructor List and the Empty data constructor are named [] and the Cons constructor is named (:).
data [] a = [] | (:) a ([] a)
which Haskell allows to be written with special syntax
data [a] = [] | a : [a]
Applying the type constructer [] to a type or type variable can be replaced by including the argument inside the [], and the symbolic constructor (because it starts with a :) can be used as an infix operator.
That is, you could write
safeTail ((:) x xs) = xs -- (3)
or
safeTail (x : xs) = xs -- (4)
with (2), (3), and (4) being equivalent to (1) above.
>>> safeTail ((:) 3 ((:) 2 ((:) 1 [])))
[2,1]
>>> safeTail (3:2:1:[])
[2,1]
>>> safeTail [3,2,1]
[2,1]
For further simplicity, Haskell represents (x:[]) as [x], (x:y:[]) as [x,y], etc.
A complete definition of safeTail would also provide a value for an empty list argument:
safeTail [] = []
or a Maybe-based definition
safeTail :: [a] -> Maybe [a]
safeTail [] = Nothing
safeTail (x:xs) = Just xs
Thats the pattern matching.
The first argument to your function safeTail is some list type. In case the argument is a non-empty list, this pattern matching will succeed and bind the x to the head element and xs to the tail of the list.
In case you pass an empty list to safeTail the pattern match will fail and other patterns (if any exists) are checked.
I'm reading Real world haskell book again and it's making more sense. I've come accross this function and wanted to know if my interpretation of what it's doing is correct. The function is
oddList :: [Int] -> [Int]
oddList (x:xs) | odd x = x : oddList xs
| otherwise = oddList xs
oddList _ = []
I've read that as
Define the function oddList which accepts a list of ints and returns a list of ints.
Pattern matching: when the parameter is a list.
Take the first item, binding it to x, leaving the remainder elements in xs.
If x is an odd number prepend x to the result of applying oddList to the remaining elements xs and return that result. Repeat...
When x isn't odd, just return the result of applying oddList to xs
In all other cases return an empty list.
1) Is that a suitable/correct way of reading that?
2) Even though I think I understand it, I'm not convinced I've got the (x:xs) bit down. How should that be read, what's it actually doing?
3) Is the |...| otherwise syntax similar/same as the case expr of syntax
1 I'd make only 2 changes to your description:
when the parameter is a nonempty list.
f x is an odd number prepend x to the result of applying oddList to the remaining elements xs and return that result. [delete "Repeat...""]
Note that for the "_", "In all other cases" actually means "When the argument is an empty list", since that is the only other case.
2 The (x:xs) is a pattern that introduces two variables. The pattern matches non empty lists and binds the x variable to the first item (head) of the list and binds xs to the remainder (tail) of the list.
3 Yes. An equivalent way to write the same function is
oddList :: [Int] -> [Int]
oddList ys = case ys of { (x:xs) | odd x -> x : oddList xs ;
(x:xs) | otherwise -> oddList xs ;
_ -> [] }
Note that otherwise is just the same as True, so | otherwise could be omitted here.
You got it right.
The (x:xs) parts says: If the list contains at least one element, bind the first element to x, and the rest of the list to xs
The code could also be written as
oddList :: [Int] -> [Int]
oddList (x:xs) = case (odd x) of
True -> x : oddList xs
False -> oddList xs
oddList _ = []
In this specific case, the guard (|) is just a prettier way to write that down. Note that otherwise is just a synonym for True , which usually makes the code easier to read.
What #DanielWagner is pointing out, is we in some cases, the use of guards allow for some more complex behavior.
Consider this function (which is only relevant for illustrating the principle)
funnyList :: [Int] -> [Int]
funnyList (x1:x2:xs)
| even x1 && even x2 = x1 : funnyList xs
| odd x1 && odd x2 = x2 : funnyList xs
funnyList (x:xs)
| odd x = x : funnyList xs
funnyList _ = []
This function will go though these clauses until one of them is true:
If there are at least two elements (x1 and x2) and they are both even, then the result is:
adding the first element (x1) to the result of processing the rest of the list (not including x1 or x2)
If there are at least one element in the list (x), and it is odd, then the result is:
adding the first element (x) to the result of processing the rest of the list (not including x)
No matter what the list looks like, the result is:
an empty list []
thus funnyList [1,3,4,5] == [1,3] and funnyList [1,2,4,5,6] == [1,2,5]
You should also checkout the free online book Learn You a Haskell for Great Good
You've correctly understood what it does on the low level.
However, with some experience you should be able to interpret it in the "big picture" right away: when you have two cases (x:xs) and _, and xs only turns up again as an argument to the function again, it means this is a list consumer. In fact, such a function is always equivalent to a foldr. Your function has the form
oddList' (x:xs) = g x $ oddList' xs
oddList' [] = q
with
g :: Int -> [Int] -> [Int]
g x qs | odd x = x : qs
| otherwise = qs
q = [] :: [Int]
The definition can thus be compacted to oddList' = foldr g q.
While you may right now not be more comfortable with a fold than with explicit recursion, it's actually much simpler to read once you've seen it a few times.
Actually of course, the example can be done even simpler: oddList'' = filter odd.
Read (x:xs) as: a list that was constructed with an expression of the form (x:xs)
And then, make sure you understand that every non-empty list must have been constructed with the (:) constructor.
This is apparent when you consider that the list type has just 2 constructors: [] construct the empty list, while (a:xs) constructs the list whose head is a and whose tail is xs.
You need also to mentally de-sugar expressions like
[a,b,c] = a : b : c : []
and
"foo" = 'f' : 'o' : 'o' : []
This syntactic sugar is the only difference between lists and other types like Maybe, Either or your own types. For example, when you write
foo (Just x) = ....
foo Nothing = .....
we are also considering the two base cases for Maybe:
it has been constructed with Just
it has been constructed with Nothing