Reputation: 2853
Apart from instance IsPerson (EmployeeRecord a)
the whole code is a part of the post General Functions with Typeclasses.
ghci
compiles the code, but printPerson
doesn't print anything. I guess it calls itself recursively.
Main> :l type-class.hs
[1 of 1] Compiling Main ( type-class.hs, interpreted )
Ok, modules loaded: Main.
*Main> printPerson $ EmployeeRecord (Student "me" 123) 11
Removing of instance IsPerson (EmployeeRecord a)
leads to the exception
Main> printPerson $ EmployeeRecord (Student "me" 123) 11
<interactive>:116:1: error:
* No instance for (IsPerson (EmployeeRecord Student))
arising from a use of `printPerson'
* In the expression:
printPerson $ EmployeeRecord (Student "me" 123) 11
In an equation for `it':
it = printPerson $ EmployeeRecord (Student "me" 123) 11
How should instance IsPerson EmployeeRecord
be implemented solve the issue with printPerson
?
data Student = Student String Int deriving Show
data Teacher = Teacher
{ teacherName:: String
, teacherAge:: Int
, teacherDepartment :: String
, teacherSalary :: Int
} deriving Show
class IsPerson a where
personName :: a -> String
personAge :: a -> Int
instance IsPerson Student where
personName (Student n _) = n
personAge (Student _ a) = a
instance IsPerson Teacher where
personName = teacherName
personAge = teacherAge
data (IsPerson a) => EmployeeRecord a = EmployeeRecord
{
employe :: a
, tenure :: Int
} deriving (Show)
instance IsPerson (EmployeeRecord a) where
personName a = personName a
personAge = undefined
printPerson :: (IsPerson a) => a -> IO ()
printPerson p = putStrLn $ personName p
Upvotes: 0
Views: 72
Reputation: 33466
Your EmployeeRecord
type is like a "box" where the type implementing IsPerson
is inside. You need to "unbox" the EmployeeRecord
in order to access the "inner" personName
.
You can do this unboxing by either pattern matching or using the employe
function.
instance IsPerson (EmployeeRecord a) where
personName (EmployeeRecord a _) = personName a
personAge (EmployeeRecord a _) = personAge a
instance IsPerson (EmployeeRecord a) where
personName = personName . employe
personAge = personAge . employe
By the way, your code makes use of the deprecated DatatypeContexts
language extension. Rather than put the constraint on a
in the EmployeeRecord
type declaration, put the constraint in your instance
declaration:
instance IsPerson a => IsPerson (EmployeeRecord a) where
Upvotes: 4