[Haskell-beginners] maybe this could be improved?
Michael P Mossey
mpm at alumni.caltech.edu
Wed Nov 11 21:15:36 EST 2009
Patrick LeBoutillier wrote:
> Michael,
>
> Your code is interesting and I'd like to run it, but I'm not to
> familiar with Maps and Monad transformers.
> Could you provide a function to create a SampleMap and a way to test
> it from ghci?
>
Sure,
import Control.Monad.Identity
import Control.Monad.Error
import Control.Monad
import qualified Data.Map as M
type Pitch = Int
type Sample = String
type SampleMap = M.Map Pitch Sample
-- Given a SampleMap and a Pitch, find the Pitch in the SampleMap
-- which is closest to the supplied Pitch and return that. Also
-- handle case of null map by throwing an error.
findClosestPitch :: SampleMap -> Pitch -> ErrorT String Identity Pitch
findClosestPitch samples inPitch = do
when (M.null samples) $ throwError "Was given empty sample table."
case M.splitLookup inPitch samples of
(_,Just _,_ ) -> return inPitch
(m1,_ ,m2) | (M.null m1) && not (M.null m2) -> case1
| not (M.null m1) && (M.null m2) -> case2
| otherwise -> case3
where case1 = return . fst . M.findMin $ m2
case2 = return . fst . M.findMax $ m1
case3 = return $ closest (fst . M.findMax $ m1)
(fst . M.findMin $ m2)
closest a b = if abs (a - inPitch) < abs (b - inPitch)
then a
else b
testMap1 = M.fromList [ (1,"sample1")
, (5,"sample2")
, (9,"sample3") ]
-- testMap2 ==> Right 1
testMap2 = runIdentity $ runErrorT $ findClosestPitch testMap1 2
-- testMap3 ==> Right 5
testMap3 = runIdentity $ runErrorT $ findClosestPitch testMap1 5
-- testMap4 ==> Left "Was given empty sample table."
testMap4 = runIdentity $ runErrorT $ findClosestPitch M.empty 5
More information about the Beginners
mailing list