I'm working on a Haskell function that is going to 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
My attempt on toPosition:
import Data.Char
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 (ord second))
else Nothing -- more than two characters
else Nothing -- invalid second character
else Nothing -- invalid first character
isValidChar :: Char -> Bool
isValidChar x
|x == 'A' = True
|x == 'B' = True
|x == 'C' = True
|x == 'D' = True
|x == 'E' = True
|x == 'F' = True
|x == 'G' = True
|x == 'H' = True
|otherwise = False
isValidInt :: Char -> Bool
isValidInt x
|x == '1' = True
|x == '2' = True
|x == '3' = True
|x == '4' = True
|otherwise = False
I tried to run it with this in the terminal:
toPosition "H2"
GHCi returning ERROR:
No instance for (Show Position) arising from a use of ‘print’
In a stmt of an interactive GHCi command: print it
Does anyone have ideas about this? Any help would be appreciated!
CodePudding user response:
OK, I've basically got it done.
Just added deriving (Show,Eq)
and a anythingElse
statement will solve the problem.
Thanks for everyone that helped me!! Love from Italy
CodePudding user response:
The reason this raises an error is because it can not print the Position
, since you did not make it an instance of Show
. You thus can implement this as:
data Position = Pos Char Int deriving Show
But your functions are also quite complicated. You can simplify isValidChar
and isValidInt
with:
isValidChar :: Char -> Bool
isValidChar x = 'A' <= x && x <= 'H'
isValidInt :: Char -> Bool
isValidInt x = '1' <= x && x <= '4'
For the toPosition
function, you can use pattern matching on a list, since a String
is a list of Char
s:
import Data.Char(digitToInt)
toPosition :: String -> Maybe Position
toPosition [c, n]
| isValidChar c && isValidInt n = Just (Position c (digitToInt n))
toPosition _ = Nothing