>> foldr, foldM, etc. derive a recursive computation from the >> recursive structure of an input list, so you have to feed >> one in. If you want to bypass the list, you could use >> IO-observations (getLine, isEOF) instead of list >> observations (head/tail, null): > >Yes you can define it,
And you can, as well. That's how common idioms come into being; there's no special magic about the folds already in existence. Just because people have done fold already for lists, trees, functors,.. doesn't mean that you won't have to define your own useful abstractions every now and then. They evolve with input from theory and practice, some forms survive, and become common. >It seems to me that there's something odd about the way the >IO monad interacts with bulk operations on files. That may be more related to IO than to the monadic approach to it (try to think it over with a world-passing approach). And if you really just want ot process text, there's interact, which worked well enough for this purpose before IO became more general and more controlable. >In particular, it seems odd that getContents should ever be the >easiest way of tackling something, Who says that? It's the laziest (as in: I don't want to invest any time in this) way, and as it exists, it is often used for quick demos, examples and explanations, e.g., here on the list.That doesn't mean you have (or want) to use it for all programs (e.g., lazy i/o has interesting interactions with concurrency:), and once you start using monadic style more, you'll develop useful abstractions for common idioms, just as it happened for list programming. Some of those are already in the standard libraries, but you'll still develop your own preferences. Haskell allows you to express those, in libraries, usually without language extensions or help from implementers. It only takes a little effort to get away from things that look convenient, but may not be in the long run. >rather than some natural operation on Monads. Monads are about the type constructor, >>=, and return. Things like getLine have been thrown into this framework for practical use, but the theory won't tell you much about them (you could take some concrete monads, and look at how folds distribute over them, then try to find a general pattern; the Meijer/Hutton "Bananas in Space" paper might be helpful). >Doing something to each line of a file is such a common kind >of computation that it ought to be easy! Who says it isn't?-) There are even several styles you could adopt, including use of interact, or use of your own abstractions on top of io-monad operations.. >It also seems wrong that end of file should be an exception >-- after all, for most files other than a terminal or >"special file", having an end is the norm. As a result, the >definition you gave strikes me as awkward (no fault of >yours!). It suggests to me that a Monad isn't quite enough. Again, nothing to do with monads - just my coding decision for that example.. If you prefer, you can redefine it using IO.isEOF (I mentioned that optimization was left to others:-). >One of the great things about fold is that you don't have to >code the test for the end: it's encapsulated in the >higher-order function. Shouldn't there be the same for IO? Isn't it? getContents = foldX (++) "" -- we drop the newlines here.. getLines = foldX (:) [] No eof-testing in sight. Note that the list fold *definition* needs to test for the empty list as well (unless you restrict yourself to infinite lists) - why else would you pass in an initial value? Just to make the comparison explicit (not tested): foldr c n l = if null l then n else let h = head l ft = foldr c n (tail l) in c h ft mif c t e = c >>= \b->if b then t else e foldX c n = do mif isEOF (return n) (do l <- getLine fls <- foldX c n return (c l fls) ) So we've mostly got a fold lifted into the io-monad, with getLine delivering the "head" (and implicitly truncating further input to the "tail"). What more do you want?-) Hth, Claus _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell