J. Doe
J. Doe

Reputation: 1

Haskell: returning strings that are before & after a given string

Given a type String, should return Strings eg. given the string "Second" should return -- > "First" , "Third" That is what is before this string and what is after it. (symmetry relationship in some sense)

Here's what I have tried so far.

between :: String ->  (String, String)
between "Second" = (“First”,"Third")
between "Third" = (“Second”,"Fourth")
between "Fourth" = (“Third”, "Fifth")

The other one I tried

data Positions =  First | Second | Third | Fourth | Fifth |

between :: Positions ->  (String,String)
between Second = (“First”,"Third")
between Third = (“Second”,"Fourth")
between Fourth = (“Third”, "Fifth")

Recevied different types of error eg. Undefined variable "?" , Improperly terminated string and Equations give different arities.

How would you fix this in order for it to function well, without any errors?

Upvotes: 0

Views: 185

Answers (2)

Wokkelsok
Wokkelsok

Reputation: 140

Respecting the signature you've proposed at the start of your question (String -> (String, String)) it could look something like this:

between :: String -> (String, String)
between x = case x of
  "Second" -> ("First","Third")
  "Third"  -> ("Second","Fourth")
  "Fourth" -> ("Third","Fifth")

Upvotes: 0

bheklilr
bheklilr

Reputation: 54068

You have two syntax errors in this code. First, you have an extra | at the end of your Positions type. I like to write my ADTs a bit differently so that it's easier to see when I've messed up:

data Positions
    = First
    | Second
    | Third
    | Fourth
    | Fifth

The other error is that you seem to have copy/pasted some non-ascii quote characters into your source around each of the first tuple elements, and that's easily fixed:

between :: Positions -> (String, String)
between Second = ("First", "Third")
between Third = ("Second", "Fourth")
between Fourth = ("Third", "Fifth")

However, I'll also point out that this could be done a bit easier using a deriving clause on your type:

data Positions
    = First
    | Second
    | Third
    | Fourth
    | Fifth
    deriving (Eq, Enum, Bounded)

between :: Positions -> Maybe (Positions, Positions)
between p =
    if p == minBound || p == maxBound
        then Nothing
        else Just (pred p, succ p)

This uses Maybe to make the function safer as well, it can't crash your program if you call between First. If you really want the strings instead, you can derive (Eq, Enum, Bounded, Show) instead and use Just (show $ pred p, show $ succ p)

Upvotes: 1

Related Questions