
Hi, In order to get a feel for Haskell, I decided to write a simple CRUD application. I stumbled upon phantom types while looking for ways to validate data in Haskell. Here is what I have done so far: {-# OPTIONS_GHC -XTemplateHaskell #-} module Foo.Entities(buildTask, Sanitise, sanitise, Task, Validated, Unvalidated, name) where import Data.Lens.Lazy ( (~=), access, (%=), mapLens, (^=), (^.), (^%=), (^%%=), (^$) ) import Data.Lens.Template ( makeLenses ) data Validated data Unvalidated data Task a = Task { _name :: String } makeLenses [''Task ] buildTask :: String -> Task Unvalidated buildTask name = Task { _name = name } class Sanitise a where sanitise :: Task a -> Either (Task Validated) String instance Sanitise Validated where sanitise t = Left t instance Sanitise Unvalidated where sanitise t | t ^. name == "" = Right "Error: the name field should be not be empty" | otherwise = Left (Task { _name = t ^. name } ) Is this the recommended way of doing something like this? Do I really need to export each lens I'm using? When I'm exporting "Task", I seem to be exporting the data type, but is there a way to export the Task constructor itself (not that I would want that)? Also, how would I go about generalizing my Sanitise typeclass, so that it would work on other data types than Task? Of course, it's quite possible that I'm reinventing the wheel and that I've missed a perfectly useable data validation module on hackage. Thanks, Emm