3
\$\begingroup\$

Some patterns are emerging ("fmap (b->a) . fmap (c->b) . .. . (IO z)"). Also infix zip is kind-of a hack.

What is:

  1. Best practice in point-free style?

  2. Best practice?

Elegance> Performance; Functional> Imperative

import qualified Data.Map.Lazy as M
import qualified Data.ByteString.Char8 as BS
fromFile :: FilePath -> IO (M.Map Char Int)
fromFile = fmap (M.fromListWith (+)) . fmap (`zip` [1,1..]) . readFile
 where readFile = fmap BS.unpack . BS.readFile
asked Aug 30, 2014 at 17:42
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Best practice would be to separate the pure operations of your program from those that actually require IO. Counting the frequency of elements in a list doesn't require any IO, so you should tease that fromFile function apart into its constituent components for reusability, testing, comprehensibility, or whatever other purpose you'd like.

frequencies :: Ord k => [k] -> Map k Int
frequencies = fromListWith (+) . (`zip` [1,1..])
fromFile :: FilePath -> IO (Map Char Int)
fromFile = fmap frequencies . fmap unpack . readFile

I'd tweak this just a bit further, using repeat from the Prelude to build the infinite list instead of abusing list ranges, and to take advantage of the Functor laws and drop a few characters. I flip back and forth on writing functions in pointfree style when it requires infix sectioning too, in this case I'd probably keep the points but I don't know that one choice is clearly better than the other.

frequencies ks = fromListWith (+) $ zip ks (repeat 1)
fromFile = fmap (frequencies . unpack) . readFile
answered Aug 30, 2014 at 20:04
\$\endgroup\$
2
  • \$\begingroup\$ Need 2 reps to Up you:). I agree on IO separation and repeat. \$\endgroup\$ Commented Aug 30, 2014 at 20:25
  • \$\begingroup\$ @xged you got it! \$\endgroup\$ Commented Sep 3, 2014 at 13:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.