このエントリーをはてなブックマークに追加
2012/11/05

mapM (\_ -> [O, X])

ほげ
ふが
あべし
ひでぶ

という入力をしたら

ほげ	ふが	あべし	ひでぶ
O	O	O	O
O	O	O	X
O	O	X	O
O	X	O	O
X	O	O	O
O	O	X	X
O	X	X	O
・・・

みたいなOXの全組み合わせのマトリクスを出力するというツールを作るというお題があったのでHaskellで作ってみた

{-# OPTIONS -Wall #-}
import Control.Applicative
import Data.List

data State = O | X deriving Show

main :: IO ()
main = do
  items <- lines <$> getContents
  printHeader items
  printMatrix $ matrix items

-- | 入力項目のリストに対するO、Xのマトリクスを返す
-- >>> matrix ["hoge","fuga","foo"]
-- [[O,O,O],[O,O,X],[O,X,O],[O,X,X],[X,O,O],[X,O,X],[X,X,O],[X,X,X]]
-- >>> matrix []
-- [[]]
matrix :: [String] -> [[State]]
matrix = mapM (\_ -> [O, X])

-- | Matrixデータを表形式で出力する
printMatrix :: [[State]] -> IO ()
printMatrix (col:cols) = do
  putStr $ listToTsv $ map show col
  putStrLn ""
  printMatrix cols
printMatrix [] = return ()

-- | ヘッダを出力する
printHeader :: [String] -> IO ()
printHeader items = do
  putStr $ listToTsv items
  putStrLn ""

-- | 文字列のリストをタブ区切りの文字列にする
-- >>> listToTsv ["hoge","fuga","bar"]
-- "hoge\tfuga\tbar"
listToTsv :: [String] -> String
listToTsv items = intercalate "\t" items

結果

runhaskell matrix.hs < test.txt
ほげ	ふが	あべし	ひでぶ
O	O	O	O
O	O	O	X
O	O	X	O
O	O	X	X
O	X	O	O
O	X	O	X
O	X	X	O
O	X	X	X
X	O	O	O
X	O	O	X
X	O	X	O
X	O	X	X
X	X	O	O
X	X	O	X
X	X	X	O
X	X	X	X

matrix関数のところがごにょごにょしてたらこんな簡単になった。Haskellすげーなと。

-- | 入力項目のリストに対するO、Xのマトリクスを返す
-- >>> matrix ["hoge","fuga","foo"]
-- [[O,O,O],[O,O,X],[O,X,O],[O,X,X],[X,O,O],[X,O,X],[X,X,O],[X,X,X]]
-- >>> matrix []
-- [[]]
matrix :: [String] -> [[State]]
matrix = mapM (\_ -> [O, X])