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 <agocorona@gmail.com> wrote:
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