I'm new to haskell.
I wrote a simple code.
But it does not work.
I'm getting this 'can not construct infinite type' error.
How does it fix.
reverse' list
| null list = []
| otherwise = (reverse' (tail list)) : (head list)
The problem arises from your use of the : operator, which has the type
(:) :: a -> [a] -> [a]
So it takes an element and a list, and returns a new list with that element prepended on. Where you have
reverse' (tail list) : head list
-- parentheses removed since they're not needed
the type of reverse' (tail list) is [a], and the type of head list is a, so the compiler tries to make it so that a ~ [a], which obviously can't work. Instead, you can use the ++ operator and put head list into a list itself:
reverse' (tail list) ++ [head list]
But keep in mind that this is not a very efficient solution, concatenation onto the end of Haskell lists is slow since they're singly linked lists.
Related
I'm trying to make a function that takes the last character from a string and add it to be the first character. In string I can do this (xs:x) and then x is the last character?
xs is just a naming convention for lists in Haskell (which you should use!). (x:xs) is a pattern matching using the (:) function, it is up to you how you name it e.g. (this:makesnosense) is also valid.
Also remember that a String is just another list, so your question is equal to: "How can I make the last element of a list the first one."
This would be one way to solve it:
lastToFirst :: [a] -> [a]
lastToFirst [] = []
lastToFirst [x] = [x]
lastToFirst xs = last xs : init xs
I'm trying to make a function that takes away the last character from a string and add it to be the first character.
In Haskell, list operator ':' is asymmetric. If the left operand is of type α, the right operand must be of type [α]. Hence, a pattern such as xs:x is just using misleading variable names. The operator is right-associative, so that x0:x1:xs means x0:(x1:xs).
Unlike Python lists, which are basically arrays, Haskell lists are just forward-chained linked lists. Classic imperative languages often maintain both a pointer to the head of a linked list and to its tail, but the main point of the tail pointer is to be able to append new elements at the tail of the list.
As Haskell lists are immutable, the tail pointer would be mostly useless, and so Haskell only maintains a pointer to the head of a list.
This means there is no cheap way to access the last element. The only way is to traverse the whole list, starting from the head. Furthermore, immutability implies that the only way to generate the [1,2,3] list from the [1,2,3,4] list is by duplicating the first 3 elements, which again require a full traversal.
So an expression such as last xs : init xs, if compiled naïvely, implies 2 costly traversals of the input list.
The best one can hope is to leverage the duplication work to grab the last element at no extra cost, thus solving the problem in a single traversal. This can be done, for example, by recursion:
makeLastFirst :: [a] -> [a]
makeLastFirst [] = [] -- empty input list
makeLastFirst [end] = [end] -- just the last element
makeLastFirst (x0:(x1:xs)) = let (end:ys) = makeLastFirst (x1:xs)
in end : (x0:ys)
where the recursive clause takes care of keeping the input tail element at the head of the output list.
Watching the gears turn:
One can visualize the recursive process by importing package Debug.Trace and using its trace function. Expression trace msg value evaluates to just value, but has the side effect of printing the msg string. Yes, side effects are normally forbidden in Haskell, but function trace has special privileges.
So we can write a more talkative version of our function:
import Debug.Trace
traceMakeLastFirst :: Show a => [a] -> [a]
traceMakeLastFirst [] = [] -- empty input list
traceMakeLastFirst [end] = [end] -- just the last element
traceMakeLastFirst (x0:(x1:xs)) = let (end:ys) = traceMakeLastFirst (x1:xs)
result = end : (x0:ys)
in trace (show result) result
Testing under the ghci interpreter:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
λ>
λ> :load q66927560.hs
...
Ok, one module loaded.
λ>
λ> traceMakeLastFirst ""
""
λ>
λ> traceMakeLastFirst "a"
"a"
λ>
λ> makeLastFirst "Mercury"
"yMercur"
λ>
λ> traceMakeLastFirst "Mercury"
""yr"
"yur"
"ycur"
"yrcur"
"yercur"
"yMercur"
yMercur"
λ>
-- makeLastFirst "abcd" == "dabc"
-- makeLastFirst "hello" == "ohell"
-- makeLastFirst "orange" == "eorang"
makeLastFirst :: [a] -> [a]
makeLastFirst lst = [ head (reverse lst) ] ++ (init lst)
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 trying to make a function in haskell but my goal is doing it by using foldr over list, this is an example:
sublistas [5,1,2]
[[],[2],[1],[1,2],[5],[5,2],[5,1],[5,1,2]]
efficiency is not an issue. What I try so far gives to me the error:
cannot construct the infinite type .....
sublistas = foldr (\x rs -> [x] ++ map (x:) rs) [[]]
I tried a long time, maybe someone could give me some ideas here?
You can use:
foldr (\x rs -> rs ++ map (x:) rs) [[]]
For example:
Prelude> foldr (\x rs -> rs ++ map (x:) rs) [[]] [5,1,2]
[[],[2],[1],[1,2],[5],[5,2],[5,1],[5,1,2]]
The proposed foldr thus works as follows: we start with a [[]]. Now for an element x, we generate the concatenation, of all lists already generated (in the first step [], and these lists prepended with the element, so [2]).
So after a first step, we obtain [[],[2]]. Next we fold again and now we generate [[],[2],[1],[1,2]]. Finally we also work with 5, resulting in [[],[2],[1],[1,2],[5],[5,2],[5,1],[5,1,2]].
The above explanation has to be seen in a lazy manner: rs is not necessary calculated (first), unless that is necessary.
Your lambda expression \x rs -> [x] ++ map (x:) rs is incorrect for two reasons:
[x] is a list containing a item of the list you provide, not a list of lists of items you provide, so a type error; and
you should not add an [x] to the result anyway: you pass all elements that are already generated, together with all the elements you prepend with x.
I have problems trying to separate a list follows, suppose we have the following lists
[[1,2,3,4], [5,6,7,8], [9,10,11,12 ], [13,14,15,16,17]].
The result should be:
[[1,5,9,13] [2,6,10,14] [3,7,11,16] [4,8,12,16]]
I'm trying to do it the following way:
joinHead (x: xs) = map head (x: xs)
separateLists (x: xs) = xs joinHead x ++ separateLists
obviously this does not work. I hope you can help me. thx.
I adapted the functions you wrote, joinHead and separateLists, to make the code work, while preserving the logic you were following. From what I could infer looking at these functions, the idea was to use joinHead to extract the first element of each child list and return a new list. Then, this new list should be inserted in the front of a list of lists returned from calling separateLists recursively.
Here is the new definition of joinHead:
joinHead :: [[a]] -> [a]
joinHead ([]:_) = []
joinHead xs = map head xs
Note that the first line checks, through pattern matching, whether the first list contained in the list of lists is empty and, if so, returns an empty list ([]). The reasons for that are two:
The function head is unsafe. That means that calling head on an empty list will cause an exception to be thrown (try running in GHCi head []);
For simplicity, I'm assuming that all the lists were already checked to have the same length (length (xs !! 0) == length (xs !! 1) ...).
The definition of separateLists is as follows:
separateLists :: [[a]] -> [[a]]
separateLists ([]:_) = []
separateLists ([x]:xs) = [joinHead ([x]:xs)]
separateLists xs = joinHead xs : separateLists (map tail xs)
Again, the first two definitions are necessary for both stopping the recursion and safety purposes. The first line says: "if the first list is empty, then all the elements of all lists were already consumed, so return []". The second line says: "if the first line has exactly one element, then just call joinHead and return the result wrapped in a list". Note that in the third definition we have a call to tail which, like head, throws exceptions when called on []. That's the reason of why we need a separate case for lists of length 1. Finally, the third line, which is executed for lists of length greater than 1, gets a list from joinHead xs and insert it (using the "cons" operator (:)) in the beginning of the list returned from recursively calling separateLists. In this call, we have to take out the first elements of all the lists, that's why we use map tail xs.
Now, running:
λ: let list = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16,17]]
λ: separateLists list
[[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]
will give you the expected results. I hope it was clear enough. As a final note, I want to point out that this implementation is far from being optimal and, as suggested in the comments, you should probably use the standard Data.List.transpose. As an exercise and didatic example, it's fine! ;-)
While working through Real World Haskell, I tried to complete the palindrome exercise using the following code solution:
palin :: [a] -> [a]
palin list = list ++ rev list
where rev list
| null list = []
| otherwise = rev (tail list) ++ (head list)
Which raised a "cannot construct an infinite type error. However, simply replacing the parenthesis around the head list with square brackets, and it works correctly, as demonstrated in the following example:
palin :: [a] -> [a]
palin list = list ++ rev list
where rev list
| null list = []
| otherwise = rev (tail list) ++ [head list]
I don't really understand why it matters, nor do I understand what does the "cannot construct infinite type a = [a]" error means. Could someone explain this?
In the last line, you are trying to append a non-list to a list. head list gives the first item of the list, which is type a. When you try to use ++ to append, you can't append something that isn't a list to a list. By appending [head list], you are appending a list of 1 item to the other list. The [] construct the single item list in this case.
Assume you are the type checker and you see a this:
(tail list) ++ (head list)
You know already, the `list is a list of something. So you start with:
list::[a]
then this must be true:
(tail list)::[a]
and this:
(head list)::a
But then there's `++ which wants both its arguments to have the same type. But this means, that
a == [a]
or by substitution:
a == [a] == [[a]] == [[[a]]] ...etc.
which is indeed an infinite type.
++ operator has type [a] -> [a] -> [a], i.e. it takes two lists of some type and produces another list of the same type. OTOH head function has type [a] -> a, i.e. it takes a list of some type and returns a value of that type. In your first example ++ got [a] on the left hand and a on the right hand. Trying to unify these types type checker produces that error. In the second example you've constructed a single-element list from the result of head and it has type [a], so type checker is happy.