簡単移調ツールをつくってみました。
id:ha-tan:20051003:1128289452でつくったRuby版移調ツールをHaskellに移植してみました。
ファイル: icho.hs
import System import Control.Monad import Data.Char import Data.Maybe import Data.List usage :: IO () usage = do putStrLn "usage: icho [from] [to]" exitFailure main :: IO () main = do args <- getArgs when (length args < 2) $ usage let fromIndex = noteIndex $ canonNote $ head args toIndex = noteIndex $ canonNote $ head $ tail args when (fromIndex < 0 || toIndex < 0) $ usage icho fromIndex toIndex where icho :: Int -> Int -> IO () icho fromIndex toIndex = do let rotateNotes = rotate (toIndex - fromIndex) notes mapM_ printNote $ zip notes rotateNotes printNote :: (String, String) -> IO () printNote (from, to) = putStrLn $ (ljust 2 from) ++ " => " ++ (ljust 2 to) ljust :: Int -> String -> String ljust width s = s ++ replicate (width - (length s)) ' ' notes :: [String] notes = [ "C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B" ] canonNote :: String -> String canonNote [] = error "internal error at canonNote." canonNote (s:ss) = [toUpper s] ++ ss noteIndex :: String -> Int noteIndex note = case elemIndex note notes of Just i -> i Nothing -> -1 rotate :: Int -> [a] -> [a] rotate i ss = let i' = if i > 0 then i else length ss + i (s1, s2) = splitAt i' ss in s2 ++ s1
以下使用例です。GからCに移調する場合。
$ ./icho.exe g c C => F C# => F# D => G Eb => G# E => A F => Bb F# => B G => C G# => C# A => D Bb => Eb B => E