Haskell passing empty Character to a function
Solution 1
You can use a Maybe
:
before :: Char -> [Char] -> Maybe Char
before x str = initialise x str
initialise x (y:xs)
| x == y = Nothing
| otherwise = trackelement x y xs
trackelement :: Char -> Char -> [Char] -> Maybe Char
trackelement x y [] = Nothing
trackelement x y (z:zs)
| x == z = Just y
| otherwise = trackelement x z zs
To take care of the corner case before 'l' "luis"
, we have to add a new initialiser function. It basically checks if the first character matches the searched one. If it does, we return Nothing
, because we checked the first character which obviously does not have a preceding one. Else we just call trackelement
and use it's result.
As Zeta mentioned, you can combine the functions, which simplifies everything and takes care of the corner case you are currently experiencing.
before _ [x] = Nothing
before a (x:y:xs)
| a == y = Just x
| otherwise = before a (y:xs)
Just using this function, you noticed you have problems when encountering a word containing more than one letter which is also searched for (before 'a' "amalia"
-> Just 'm'
). Currently the best solution I know of is again splitting this up into more than one function, which brings us back to the solution at the top.
Solution 2
The answers shown already are good for getting your code to work, but they don't explain why you get the error you're receiving. The reason why that error was shown is that ''
is not valid syntax, since there is no such thing as an "empty character". All characters have value, but String
s can be empty. Remember that type String = [Char]
, and it's very clear that there can be such a thing as an empty list, but characters always have a value. It's comparable to saying you can have an empty list of Int
s, namely []
, but you can't have an "empty int", whatever that would mean.
Solution 3
Match the first two elements instead just head and tail. That way you don't even need trackelement
:
before :: Eq a => a -> [a] -> Maybe a
before x (a:b:rest)
| a == x = Nothing
| b == x = Just a
| otherwise = before x (b:rest)
before _ _ = Nothing
Luis Armando
Updated on June 04, 2022Comments
-
Luis Armando over 1 year
I'm working in Haskell in two functions:
Basically I want to get the character before matching a specific character in a given string
This is my code:
before :: Char -> [Char] -> Char before x str = trackelement x ' ' str trackelement :: Char -> Char -> [Char] -> Char trackelement x y (z:zs) | x == z = y | otherwise = trackelement x z (zs)
My problem is when I try:
before 'l' "luis"
The answer is :
' '
(of course, before'l'
there is nothing), and I would like to be''
orNothing
I tried passing
trackelement x '' str
instead oftrackelement x ' ' str
but I have this errorSyntax error on ''str
Could you suggest me something?
-
Luis Armando about 9 yearsI have tried your solution, but the result is
Just 'l'
orJust ' '
I need only the'l'
or''
. I never worked withMaybe
-
Zeta about 9 yearsActually, the question was edited and the problem wasn't in there at the time we wrote the answers ^^".
-
ThreeFx about 9 years@LuisArmando The problem is that a possible match is given at the beginning. Combining the functions as Zeta did is the best practice.
-
bheklilr about 9 years@Zeta Ah, I had not realized. Regardless, I just wanted to see it addressed. Personally, I think your answer provides the best solution for getting a working algorithm (ThreeFx's is good, but is a little lengthy in comparison), I just wanted all bases to be covered so that OP understood more fully what was going on.
-
Luis Armando about 9 yearsyour answer is not working properly I tried
before 'a' "amalia"
and the response wasJust 'm'
. This is wrong because it have to match with the first'a'
not with the latest ;) -
ThreeFx about 9 years@LuisArmando `´Just 'm'`` is the middle
'a'
^^ This happens because the checking starts too late. -
chi about 9 yearsI'd add a case for the empty list in
before
.