Luis Armando
Luis Armando

Reputation: 454

Haskell passing empty Character to a function

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 '' or Nothing

I tried passing trackelement x '' str instead of trackelement x ' ' str but I have this error Syntax error on ''str

Could you suggest me something?

Upvotes: 4

Views: 13341

Answers (3)

Zeta
Zeta

Reputation: 105905

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

Upvotes: 3

ThreeFx
ThreeFx

Reputation: 7360

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.

Upvotes: 4

bheklilr
bheklilr

Reputation: 54068

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 Strings 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 Ints, namely [], but you can't have an "empty int", whatever that would mean.

Upvotes: 6

Related Questions