Smart constructors is a technique to
place constraints on on the construction of values by using smart constructors.
Let me try to explain with an example.
Person.hs
type Height = Float type Weight = Float type Name = String data Category = Male | Female data Person = Person Name Category Weight Height deriving Show
Just observe the definition of type
Person, do you think anything wrong with this definition. Yes it is, value
constructor Person has fields like Weight, Height Which are of type Float.
Since we are not doing any validation on these types, user can able to define a
Person variable by giving –ve values to Height and Weight fields, which is
completely wrong.
Prelude> :load Person.hs [1 of 1] Compiling Main ( Person.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> let person1 = Person "Srinu" Male (-16) (-19.8) *Main> *Main> person1 Person "Srinu" Male (-16.0) (-19.8)
Smarter
constructors
Smart constructors are nothing but functions
that build values of the required type, but perform some extra checks when the
value is constructed.
Person.hs
module Person (getPerson) where type Height = Float type Weight = Float type Name = String data Category = Male | Female deriving Show data Person = Person Name Category Weight Height deriving Show getPerson :: Name -> Category -> Weight -> Height -> Person getPerson name category weight height | (weight < 0) || (weight > 1000) = error "Invalid Weight" | (height < 0) || (height > 10) = error "Invalid Height" | otherwise = Person name category weight height
Observe above snippet, I hide the
definition of Person from this module. Outside of this module must call the
function getPerson to get Person variable. getPerson function performs checks
on the arguments before returning Person variable.
Prelude> :load Person.hs [1 of 1] Compiling Person ( Person.hs, interpreted ) Ok, modules loaded: Person. *Person> *Person> *Person> getPerson "Hari" Male 71 5.8 Person "Hari" Male 71.0 5.8 *Person> *Person> getPerson "Hari" Male 71 (-10) *** Exception: Invalid Height *Person> *Person> getPerson "Hari" Male (-9) (-10) *** Exception: Invalid Weight *Person>
No comments:
Post a Comment