
On 5 Dec 2008, at 16:42, Apfelmus, Heinrich wrote:
Thomas Davie wrote:
You don't even need a type class, a simple data type is enough.
Very true, but I disagree that you've made it functional in any way, IO is all about sequencing things, it's very much not a functional style
data Engine = Engine { foo :: IO (), bar :: String -> IO () }
This is much nicer done as functions from String -> String
Sure, I agree. I was just replicating foo and bar from the OP because I don't know what kind of effect he had in mind. I mean, instead of merely mapping each command in isolation, he could want to accumulate a value or read files or something.
Sure, and he could then use a fold instead of a map. Reading files is problematic, but as long as you're only doing it once (the most common situation) is entirely fine wrapped up in an unsafePerformIO. Either way, the question was how to do it functionally, and to do it functionally, and with all of the nice shiny benefits we get with functional code like composibility and orthogonality, you need to do it with String -> String. Bob