[Haskell-cafe] applicative challenge

Thomas Davie tom.davie at gmail.com
Tue May 5 10:13:14 EDT 2009


> I also tried
>
> t15 =
>  let grabby = unlines . takeWhile (not . blank) . lines
>      top = ("first time: " ++) . grabby . ("second time: " ++) .  
> grabby
>  in  interact top
>
>
> but that didn't work either:
>
> thartman at ubuntu:~/haskell-learning/lazy-n-strict>runghc sequencing.hs
> a
> first time: second time: a
> b
> b
>
> If someone can explain the subtleties of using interact when you run
> out of stdio here, it would be nice to incorporate this into

Essentially, what's happening here is that interact consumes *all* of  
standard input, and runs your function on it.  This means that as  
you've realised here, your function must do *all* of the processing of  
input in one go – but this is good!  This means our IO is restricted  
to one tiny little corner of the program, and we get to write pure  
Haskell everywhere else :)

What's going on with your top function on the other hand is that (.)  
is not `after` in the sense you're thinking.

If you want one grabby to consume some of the input, but not all of it  
you'd need to return a pair containing the output, and the unconsumed  
input.

> where it talks about how using interact is the easy way to approach
> these types of problems. Not *that* easy though, as this scenario
> suggests.

The key here is that it's more composable than using IO – IO can  
change all kinds of wierd state, and result in two functions doing  
totally different things depending on when they're called.  This means  
you can't reliably stick bits of IO code together.  With pure  
functional code though, referential transparency guarentees that you  
can.

Bob


More information about the Haskell-Cafe mailing list