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)
Related
I'm writing an algorithm in Haskell that simplifies context-free grammars and I've been struggling with the removal of null productions, more specifically with the "substitution" of nullable non-terminals in the other productions.
Given a string, let's say "ASA", I would like to return a list of strings built by removing the character "A" one, two, ... every time it appears.
To be clear, given "ASA" I'd like to return this: ["SA", "AS", "S"].
In Python I did it quite easily, but in Haskell I don't know how to iterate over the string and manipulate it how I'd like to. Probably because I'm still not used tu functional programming.
A library-based approach:
A given input character may or may not be in any of the output partial strings. So it seems natural to involve the Haskell Maybe type transformer. It is similar to std::optional in C++.
We can have an expand function that associates to each input character a list of the corresponding possibilities:
$ ghci
λ>
λ> st = "ASA"
λ>
λ> expand ch = if (ch == 'A') then [ Just ch, Nothing ] else [ Just ch ]
λ>
λ> map expand st
[[Just 'A',Nothing],[Just 'S'],[Just 'A',Nothing]]
λ>
What we need is basically the Cartesian product of the above lists of possibilites. A list Cartesian product can be obtained by using the highly polymorphic sequence library function:
λ>
λ> sequence (map expand st)
[[Just 'A',Just 'S',Just 'A'],[Just 'A',Just 'S',Nothing],[Nothing,Just 'S',Just 'A'],[Nothing,Just 'S',Nothing]]
λ>
Next, we need to change for example [Just 'A', Just 'S', Nothing] into ['A', 'S'], which in Haskell is exactly the same thing as "AS". The required function would have as its type signature:
func :: [Maybe α] -> [α]
If we submit this candidate type signature into Hoogle, we readily get library function catMaybes:
λ>
λ> import qualified Data.Maybe as Mb
λ>
λ> Mb.catMaybes [Just 'A',Just 'S',Nothing]
"AS"
λ>
λ> map Mb.catMaybes (sequence (map expand st))
["ASA","AS","SA","S"]
λ>
and we just have to remove the full string "ASA" from that last list.
Of course, there is no need to restrict this to the Char data type. Any type with a proper equality test can do. And the privileged character 'A' should be made into a variable argument. Overall, this gives us the following code:
import qualified Data.Maybe as Mb
multiSuppressor :: Eq α => α -> [α] -> [[α]]
multiSuppressor e xs =
let expand e1 = if (e1 == e) then [ Just e1, Nothing ] else [ Just e1 ]
maybes = sequence (map expand xs)
res1 = map Mb.catMaybes maybes
in
-- final massaging as the whole list is normally unwanted:
if (null xs) then [[]] else filter (/= xs) res1
A note on efficiency:
Function sequence is polymorphic. Being the list cartesian product is not its sole role in life. Unfortunately, this happens to have the sad side effect that its memory consumption can become quite large if you go beyond toy-sized examples.
If this becomes a problem, one can use the following replacement code instead, which is based on an idea by K. A. Buhr:
cartesianProduct :: [[α]] -> [[α]]
cartesianProduct xss =
map reverse (helper (reverse xss))
where
helper [] = [[]]
helper (ys:zss) = [y:zs | zs <- helper zss, y <- ys]
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! ;-)
I'm a beginner of Haskell and I'm trying to divide a list into two sublists with approximate equal size. The module can be loaded but when I tried to run ghci, it does not work.
For example:
divideList [1,2,3,4] = [1,2] [3,4] divideList [1,2,3,4,5] = [1,2,3] [4,5]
divideList [] = ([],[])
divideList [x] = ([x],[])
divideList ((x:xs):ys) = if a < b
then splitAt (a+1) ((x:xs):ys)
else divideList (xs:ys)
where a = length xs
b = length ys
It said that "No instance for (Num[t0]) arising from the literal '2'". I don't know how to fix it. Can anyone help me??? Thanks!
Here's the error indicated when I typed divideList [2,3,5] in ghci.
<interactive>:2:13:
No instance for (Num[a0]) arising from literal '2'
Possible fix: add an instance declaration for (Num[a0])
In the expression: 2
In the first argument of 'divideList', namely "[2,3,5]
In the expression: divideList [2,3,5]
First off: Dude, where's my {formatting, type signatures}?
Second: The error you are talking about indicates you have used a numeric literal (ex: 1) in a place where the types say the value should be a list. Because interpreting literals is flexible (polymorphic), the type checker complains that you need to tell it how to interpret a number as list.
Third: The posted code (reformatted and provided a type signature below) does not produce the error you claim.
Fourth: The posted code does not perform the task you describe - the type signature alone is a strong hint - the function you described should take lists to pairs of lists ([a] -> ([a],[a]) but you defined a function that consumes lists of lists ([[a]] -> ([[a]],[[a]]))...
divideList :: [[a]] -> ([[a]], [[a]])
divideList [] = ([],[])
divideList [x] = ([x],[])
divideList ((x:xs):ys) =
if a < b
then splitAt (a+1) ((x:xs):ys)
else divideList (xs:ys)
where a = length xs
b = length ys
As Thomas says, if you write out the type signature before you write the implementation, it should generally give you a greater feel for what you want your code to be doing.
If I'm correct in understanding your code, you were intending on starting from the left of the provided list, and advancing through until the left-hand side of the list is greater than or equal to in size as the right hand side, at which point you split it.
If this is the case, then there are a couple of bugs in your code:
Your current logic is if a < b then split, where a = length xs (supposed left-hand side) and b = length ys (supposed right-hand side). Assuming you start from the left, the left-hand side will be smaller than the right hand side to begin with! So in this case, you should probably have a > b instead.
Your use of pattern matching is incorrect - (x:xs):ys means "take the first element of the list as (x:xs), which is a single element x plus the rest of the list xs, then the rest as ys". So this pattern matching is trying to turn the first element of the list (2) into a list so it can extract (x:xs) from it, which is where your error is coming from.
If you wish to split the list roughly in half, I would simply do something more like
mySplit list = splitAt ((length list) `div` 2) list
which is much simpler :)
I am trying to implement Standard words function of Haskell. I am using State Monad to solve the problem.
My Code is :
type WorS = ([String],String,String)
words' :: State WorS [String]
words' = do
(lwords, words, x:xs) <- get
case x:xs of
(' ':xs) -> (put (words:lwords, [], xs) >> words')
([]) -> return lwords
(_:xs)-> (put (lwords, words ++ [x], xs) >> words')
run_word' :: String ->[String]
run_word' x = reverse $ fst (runState words' ([], [], x))
When I do:
run_word' "guns and roses"
I get this error:
Exception: Pattern match failure in do expression
The code is loading in ghci without any error. What am I doing wrong?
(lwords,words,x:xs)<-get
x:xs matches a list with at least one element (x becomes the first element, and xs becomes the rest of the list), so you get a pattern match failure when the third member of the tuple is [].
Solution: replace
(lwords,words,x:xs)<-get
case x:xs of
with
(lwords,words,xs)<-get
case xs of
(And consider using different variable names later in the function: it gets confusing when you have two or more variables with the same name.)
Edit: if you turn on warnings (pass the -Wall flag to ghc/ghci), you will get warned at compile time that the pattern may fail to match at runtime. (You'll also get a warning about having one xs variable hiding another xs variable, called shadowing.)
Since there is a way to bind the head and tail of a list via pattern matching, I'm wondering if you can use pattern matching to bind the last element of a list?
Yes, you can, using the ViewPatterns extension.
Prelude> :set -XViewPatterns
Prelude> let f (last -> x) = x*2
Prelude> f [1, 2, 3]
6
Note that this pattern will always succeed, though, so you'll probably want to add a pattern for the case where the list is empty, else last will throw an exception.
Prelude> f []
*** Exception: Prelude.last: empty list
Also note that this is just syntactic sugar. Unlike normal pattern matching, this is O(n), since you're still accessing the last element of a singly-linked list. If you need more efficient access, consider using a different data structure such as Data.Sequence, which offers O(1) access to both ends.
You can use ViewPatterns to do pattern matching at the end of a list, so let's do
{-# LANGUAGE ViewPatterns #-}
and use reverse as the viewFunction, because it always succeeds, so for example
printLast :: Show a => IO ()
printLast (reverse -> (x:_)) = print x
printLast _ = putStrLn "Sorry, there wasn't a last element to print."
This is safe in the sense that it doesn't throw any exceptions as long as you covered all the possibilities.
(You could rewrite it to return a Maybe, for example.)
The syntax
mainFunction (viewFunction -> pattern) = resultExpression
is syntactic sugar for
mainFunction x = case viewFunction x of pattern -> resultExpression
so you can see it actually just reverses the list then pattern matches that, but it feels nicer.
viewFunction is just any function you like.
(One of the aims of the extension was to allow people to cleanly and easily use accessor functions
for pattern matching so they didn't have to use the underlying structure of their data type when
defining functions on it.)
The other answers explain the ViewPatterns-based solutions. If you want to make it more pattern matching-like, you can package that into a PatternSynonym:
tailLast :: [a] -> Maybe ([a], a)
tailLast xs#(_:_) = Just (init xs, last xs)
tailLast _ = Nothing
pattern Split x1 xs xn = x1 : (tailLast -> Just (xs, xn))
and then write your function as e.g.
foo :: [a] -> (a, [a], a)
foo (Split head mid last) = (head, mid, last)
foo _ = error "foo: empty list"
This is my first day of Haskell programming and I also encountered the same issue, but I could not resolve to use some kind of external artifact as suggested in previous solutions.
My feeling about Haskell is that if the core language has no solution for your problem, then the solution is to transform your problem until it works for the language.
In this case transforming the problem means transforming a tail problem into a head problem, which seems the only supported operation in pattern matching. It turns that you can easily do that using a list inversion, then work on the reversed list using head elements as you would use tail elements in the original list, and finally, if necessary, revert the result back to initial order (eg. if it was a list).
For example, given a list of integers (eg. [1,2,3,4,5,6]), assume we want to build this list in which every second element of the original list starting from the end is replaced by its double (exercise taken from Homework1 of this excellent introduction to Haskell) : [2,2,6,4,10,6].
Then we can use the following:
revert :: [Integer] -> [Integer]
revert [] = []
revert (x:[]) = [x]
revert (x:xs) = (revert xs) ++ [x]
doubleSecond :: [Integer] -> [Integer]
doubleSecond [] = []
doubleSecond (x:[]) = [x]
doubleSecond (x:y:xs) = (x:2*y : (doubleSecond xs))
doubleBeforeLast :: [Integer] -> [Integer]
doubleBeforeLast l = ( revert (doubleSecond (revert l)) )
main = putStrLn (show (doubleBeforeLast [1,2,3,4,5,6,7,8,9]))
It's obviously much longer than previous solutions, but it feels more Haskell-ish to me.