Most of your data declarations can probably be simple type aliases.
type Name = String
type Age = Int
type Iq = Int
type Language = String
With these aliases, there is no significant difference (record syntax aside) between the two constructors for DataSubject. Get rid of one, and dispense with makeDataSubject. (Unless you want to encapsulate some logic or prevent pattern matching, you don't need a smart constructor to do what you are doing.)
data DataSubject = DS { name :: Name
, age :: Age
, iq :: Iq
, language :: Language
} deriving (Show)
main = do
let x = DS { name="Ron", age=34, iq=100, language="French"}
putStrLn $ show x
If you do want real types, not just aliases, use newtype instead of data.
newtype Name = Name String deriving Show
newtype Age = Age Int deriving Show
newtype Iq = Iq Int deriving Show
newtype Language = Language String deriving Show
data DataSubject = DS { name :: Name
, age :: Age
, iq :: Iq
, language :: Language
} deriving (Show)
main = do
let x = DS { name=Name "Ron", age=Age 34, iq=Iq 100, language=Language "French"}
putStrLn $ show x
You might want to add a smart constructor here, but have it take each piece of data as a separate argument (wrapped or unwrapped), not a single argument that is already the return value up to isomorphism. (That is, your constructor was essentially the identity function other than some repackaging of the input.)
makeDataSubject :: String -> Int -> Int -> String -> DataSubject
makeDataSubject name age iq lang = DS {name=Name name, age=Age age, iq=Iq iq, language=Language lang}
or
makeDataSubject' :: Name -> Age -> Iq -> Language -> DataSubject
makeDataSubject' name age iq lang = DS {name=name, age=age, iq=iq, language=lang}
DataSubjecttype doesn't make much sense to me. What is the difference between aDSInformationandDSConstructand why are they constructors of the same type? Why doesn't simplyDSConstructsuffice instead ofmakeDataSubject?