Home > database >  Converting Strings into my own data type and vice versa
Converting Strings into my own data type and vice versa

Time:05-03

I'm working on a Haskell school assignment that asks me to convert a string to a self-defined data type : Position, which should only consist a char of (A-H) and an Int(1-4).(i.e A1, B3, H4)

Here is the function's usage: toPosition gives Just the Position named by the string, or Nothing if the string is not a valid Position name.

Here is my try: I defined the data type as:

data Position = Pos Char Int

Then my attempt on toPosition:

toPosition :: String -> Maybe Position
toPosition [] = Nothing
toPosition (x:xs) 
           | len(xs) == 1 = Loc x xs
           | otherwise = Nothing

GHCi returning

 'Not in scope: type constructor or class ‘Pos’'

Any ideas to fix this and validate the input so that it will only return a string when the input is a legal 'Position'?

---Update No.1----

I updated my code into the following:

type Position = Pos Char Int

toPosition :: String -> Maybe Position
toPosition string = case string of
  first : second : rest ->
    if isValidChar first
      then if isValidInt second
        then if null rest
          then Just (Pos first (read second :: Int))
          else Nothing -- more than two characters
        else Nothing -- invalid second character
      else Nothing -- invalid first character

isValidChar :: Char -> Bool
isValidChar x
    |x == "A" || "B" || "C" || "D" || "E" || "F" || "G" || "H" = True
    |otherwise = False

isValidInt :: Char -> Bool
isValidInt x
    |x == 1 || 2 || 3 || 4 = True
    |otherwise = False

It still gives me error:

Not in scope: type constructor or class ‘Pos’

So I'm wondering how can I represent my self-defined data type so that I don't get any more errors?

CodePudding user response:

Since this is homework I won't provide a complete solution, but hopefully I can give enough to get you unstuck.

You can use pattern matching to get the first and second characters out of the string. Then you can use normal functions to determine if those characters are valid or not. Assuming that they are, you can build a Position value to return.

data Position = Pos Char Int

toPosition :: String -> Maybe Position
toPosition string = case string of
  first : second : rest ->
    if isValidChar first
      then if isValidInt second
        then if null rest
          then Just (Pos first (charToInt second))
          else Nothing -- more than two characters
        else Nothing -- invalid second character
      else Nothing -- invalid first character
  anythingElse -> Nothing -- fewer than two characters

isValidChar :: Char -> Bool
isValidChar = undefined

isValidInt :: Char -> Bool
isValidInt = undefined

charToInt :: Char -> Int
charToInt = undefined
  • Related