-- Author: Andy Stewart -- Maintainer: Andy Stewart -- -- Copyright (C) 2010 Andy Stewart, all rights reserved. -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . module Text.Morse ( morseCode, toMorseCode ) where import Data.Char import Data.Map (Map) import qualified Data.Map as M -- | Morse code convert map. morseCode :: Map Char String morseCode = M.fromList [('a', ".-") ,('b', "-...") ,('c', "-.-.") ,('d', "-..") ,('e', ".") ,('f', "..-.") ,('g', "--.") ,('h', "....") ,('i', "..") ,('j', ".---") ,('k', "-.-") ,('l', ".-..") ,('m', "--") ,('n', "-.") ,('o', "---") ,('p', ".--.") ,('q', "--.-") ,('r', ".-.") ,('s', "...") ,('t', "-") ,('u', "..-") ,('v', "...-") ,('w', ".--") ,('x', "-..-") ,('y', "-.--") ,('z', "--..") ,('=', "-...-") ,('?', "..--..") ,('/', "-..-.") ,(',', "--..--") ,('.', ".-.-.-") ,(':', "---...") ,('\'', ".----.") ,('-', "-....-") ,('(', "-.--.-") ,(')', "-.--.-") ,('0', "-----") ,('1', ".----") ,('2', "..---") ,('3', "...--") ,('4', "....-") ,('5', ".....") ,('6', "-....") ,('7', "--...") ,('8', "---..") ,('9', "----.") ,('Ä', ".-.-") ,('Æ', ".-.-") ,('Á', ".--.-") ,('Å', ".--.-") ,('ß', ".../...") ,('É', "..-..") ,('Ñ', "--.--") ,('Ö', "---.") ,('Ø', "---.") ,('Ü', "..--") ,('@', ".--.-.")] -- | Convert String to morse code. -- If character not in 'morseCode', don't convert. toMorseCode :: String -> String toMorseCode = concatMap (\x -> case findMinMatch morseCode (\ k _ -> k == toLower x) of Just (_, morse) -> morse Nothing -> [x]) -- | Find min match one. findMinMatch :: Ord k => Map k a -> (k -> a -> Bool) -> Maybe (k, a) findMinMatch map fun = match where filterMap = M.filterWithKey fun map match = if M.null filterMap then Nothing else Just $ M.findMin filterMap