8
\$\begingroup\$

I wrote a function that inserts or updates a Map key value depending on whether the key is already in the map. If it is, then the value gets added to the already existing map's value.

import Data.Map as Map
updateMap :: (Ord k, Num v) => k -> v -> Map k v -> Map k v
updateMap k v map = if member k map then Map.adjust (+ v) k map
 else Map.insert k v map 

Tests

*Main> updateMap 1 1 $ Map.singleton 1 100
fromList [(1,101)]
*Main> updateMap 2 1 $ Map.singleton 1 100
fromList [(1,100),(2,1)]
*Main> updateMap 1 33 $ Map.singleton 1 100
fromList [(1,133)]

Please critique.

asked Jul 23, 2014 at 20:17
\$\endgroup\$

1 Answer 1

13
\$\begingroup\$
updateMapPF :: (Ord k, Num a) => k -> a -> Map k a -> Map k a
updateMapPF = Map.insertWith (+)
λ> updateMapPF 1 1 $ Map.singleton 1 100
fromList [(1,101)]
λ> updateMapPF 2 1 $ Map.singleton 1 100
fromList [(1,100),(2,1)]
λ> updateMapPF 1 33 $ Map.singleton 1 100
fromList [(1,133)]

Process:

Notice the use of Map.insert

Notice that you are mapping (+) over the possibility of having or not having a value

Notice that Data.Map has a function for applying functions to values, called Data.Map.insertWith. It's extremely common for collections to have a helper function for "insert data with a helper function / default value"

Notice the shared structure of the types of your function and insertWith

insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
updateMap :: (Ord k, Num v) => k -> v -> Map k v -> Map k v

Realize that applying (+) to insertWith will make the types identical

λ> :t insertWith
insertWith
 :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
λ> :t insertWith (+)
insertWith (+) :: (Ord k, Num a) => k -> a -> Map k a -> Map k a

Validate assumptions with specific examples, more rigor is available with the use of QuickCheck.

λ> updateMapPF 1 1 $ Map.singleton 1 100
fromList [(1,101)]
λ> updateMapPF 2 1 $ Map.singleton 1 100
fromList [(1,100),(2,1)]
λ> updateMapPF 1 33 $ Map.singleton 1 100
fromList [(1,133)]

This is a practically golden opportunity to demonstrate how eta reduction can simplify code and kill off redundant logic.

answered Jul 23, 2014 at 20:57
\$\endgroup\$
0

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.