[Haskell-cafe] Lift data from IO to Validation
Viktor Dukhovni
ietf-dane at dukhovni.org
Sat Jan 4 15:50:22 UTC 2020
On Sat, Jan 04, 2020 at 08:28:50PM +0530, Debasish Ghosh wrote:
> I am trying to validate a bunch of inputs and found the package
> Data.Validation. I am also using Data.Time for date and time. I have a
> function like this.
>
> validateOpenDate :: ZonedTime -> Validation [String] ZonedTime
>
> It's supposed to validate a date for which I need to fetch the current
> date and time. I can do that with getZonedTime :: IO ZonedTime. I want
> to check if the current time is less than the date time I pass to the
> function and return an appropriate Validation.
This function is not pure. It needs an external input that affects its
output. Therefore, the honest type of this function is either:
-- | Validate date relative to current time
validateOpenDate :: ZonedTime -> IO (Validation [String] ZonedTime)
or (with the caller doing the time lookup):
-- | Validate date relative to supplied time
validateOpenDate :: ZonedTime -> ZonedTime -> Validation [String] ZonedTime
The "supplied time could be generalized to an "Environment" that carries
whatever context information might be needed:
type Env = Env { curTime :: !ZonedTime }
With all the validation functions now:
validateOpenDate :: ZonedTime -> Reader Env (Validation [String] ZonedTime)
validateOpenData inputDate = do
now <- asks curTime
if inputDate > now
then ...
else ...
and then
import Control.Monad.Reader
main :: IO ()
main = do
env <- Env <$> getZonedTime
flip runReader env $ do
-- computations doing validation relative to the environment
> The question is how do I lift the result from IO into the Validation?
The only way to do that without changing the output type is to lie, and
use "unsafePerformIO" to extract the date inside a pure function. This
is not recommended.
> Or is there any alternative strategy that I should consider for this
> validation ? I have a number of other validations which follow the
> same strategy but don't have the IO. My final goal is to be able to
> compose all these validations applicatively to prepare a final ADT in
> a smart constructor.
You should be able "compose" the validations in the context of an
environment. Either Monadically, or Applicatively.
--
Viktor.
More information about the Haskell-Cafe
mailing list