[Haskell-beginners] Phantom types and export lists

Emmanuel Surleau emmanuel.surleau at gmail.com
Sat Oct 20 09:41:29 CEST 2012


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.



More information about the Beginners mailing list