
This is starting to look promising. I think what would be really
interesting would be to abstract out the validation logic so that it could
be presented in a more declarative fashion, something like
itemPrice *> \item inputPrice ->
if inputPrice > 0 then return inputPrice
else fail ("invalid item price for item " ++ show
(item,inputPrice))
itemTotal *> \item _ -> do
price <- need $ itemPrice item
qty <- need $ itemQty item
return $ price * qty
itemizedVat *> \item _ -> do
vatExempt <- need $ vatStatus . client . invoice $ item
if vatExempt then return 0 else do
total <- need $ itemTotal item
rate <- need $ vatRate item
return $ calcVatForValue total rate
total *> \invoice _ -> do
itemTotals <- forM (items invoice) $ \item -> (,) <$> need
(itemTotal item) <*> need (itemizedVat item)
let (itemVals,vatVals) = unzip itemTotals
subTotal = sum itemVals
vatTotal = sum vatVals
return $ Total { subTotal, vatTotal, fullTotal = subTotal+vatTotal }
Inspired by the shake build system. Off the top of my head, so there's no
system I know of that implements something like this. But it might be a
nice way to declare complex validation rules, perhaps? Error handling
could be handled by individual rules, so we know if there's a valid
itemPrice and itemQty, the itemTotal is valid too.
It might be tricky to implement this exactly as-is, I'm using "itemTotal"
as both a tag to specify a rule match and also a field name. And typing
some of the input/output stuff might be non-trivial. Seems like something
that could benefit from a specialized DSL.
John L.
On Thu, Aug 14, 2014 at 5:06 AM, Alberto G. Corona
Formlets ever had cascade validation:
data Item= Item{ name ::String, quantity, price :: Int}
Item <$> <*> inputString `validate` nonEmpty <*> inputInt <*> inputInt `validate` ( \item -> do if theUniverseIsSpanding then do if name item == "carrots" && price=="10" then fail "we don´t like 10 cent carrots in an expanding universe" else if.....
2014-08-14 11:41 GMT+02:00 Tom Ellis < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk>:
On Thu, Aug 14, 2014 at 11:28:53AM +0200, Wojtek Narczyński wrote:
On 14.08.2014 09:19, Tom Ellis wrote:
On Wed, Aug 13, 2014 at 05:21:28PM -0700, John Lato wrote:
On Wed, Aug 13, 2014 at 4:21 PM, Tom Ellis
data LineItem = LineItem { name :: Maybe String , quantity :: Maybe Quantity , price :: Maybe Price }
Rather than this definition, what about something like:
data LineItemF f = LineItem { name :: f String , quantity :: f Quantity , price :: f Price } It seems Wojtek already objected to this approach, though perhaps that objection could be overcome
Hmm, perhaps like this
LineItemFi = LineItemFi { name :: StringFi , quantity :: QuantityFi , price :: PriceFi }
data LineItemUi f = LineItemUi { name :: StringUi , quantity :: QuantityUi , price :: PriceUi }
You didn't use f there. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Alberto.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe