In the process of learning haskell today I found this tutorial and followed it and wrote my own version of wc. Here's the code:
import System.Environment
import Data.List
data Countable = CList [String] | CString String
count (CList s) = length s
count (CString s) = length s
main = do
[f] <- getArgs
s <- readFile f
putStr (wc s)
putStrLn (" " ++ f)
wc s= unwords (map (show . count) [CList (lines s), CList (words s), CString s])
I made use of a few haskell-ism already. The main work is in the last line, which is written in a pure functional way, while the main = do block is the imperative file IO stuff. I made use of functional composition: show . count. The length function, although works for either strings or lists, cannot in itself be used with the map function because in haskell members of a list must have the same type. This is why I also created my own datatype Countable with a count method for counting either lists of strings or the size of a string.
It's interesting that when you take a step back from this, you realize that most people coming from the imperative world would not understand what this program is doing at all.