On Tue, 2004-03-23 at 15:29, Sean E. Russell wrote: > Here's my base case: > > someFunc :: String -> IO [a] > ... > ax <- someFunc a > bx <- someFunc b > assertBool "fail" $ length ax == length bx > > I don't like the assignments; the typing is redundant, if I have a lot of > asserts like this, and the "variables" are temporary. What I'd much rather > have is: > > ... > assertBool "fail" $ (length $ someFunc a) == (length $ someFunc b) > > which is more readable, to my eye. > > The only solution which has been suggested that may work is liberal use of the > liftM variants, but this gets *really* tedious and obtuse. > > Is there an elegant way to do what I want to do, or am I stuck with > procedural-style assignments and bunches of temp vars?
For a project I did which involved a lot of monadic code I used some combinators which allow you to write in a more applicative/functional style but still thread the monad state through everything. Basically instead of writing: do a' <- foo a b' <- foo b c' <- foo c return $ f a' b' c' you write: f $> foo a <$> foo b <$> foo c Unfortunately it doesn't work so well with infix operators, you'd have to say (==) $> firstThing <$> secondThing which is not quite so appealing. Your example would look like so: assertBool "fail" <$$> (==) $> (length $> someFunc a) <$> (length $> someFunc b) Here's the little combinator library, it's really just a matter of using infix versions of standard monad functions and playing with their left/right associativity and precedence. import Monad (liftM, ap) infixl 1 $>, <$> --same as liftM & ap, but left associative infix infixr 0 <$$> --same as =<<, but different precedence ($>) :: Monad m => (a -> b) -> (m a -> m b) ($>) = liftM (<$>) :: Monad m => m (a -> b) -> (m a -> m b) (<$>) = ap (<$$>) :: Monad m => (a -> m b) -> (m a -> m b) (<$$>) = (=<<) -- Duncan _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell