如何在Haskell中重构此代码

时间:2014-08-21 15:30:10

标签: haskell

我制作了这个简单的代码,在终端上绘制字母。 如何使用Prelude函数重构此代码? 当然,也可以使用其他库。

import Data.Char

letterDatabase = [
[
"AAAAA ",
"A   A ",
"AAAAA ",
"A   A ",
"A   A "
],
[
"BBBB  ",
"B   B ",
"BBBB  ",
"B   B ",
"BBBB  "
],
[
"CCCCC ",
"C     ",
"C     ",
"C     ",
"CCCCC "
],
[
"DDD   ",
"D  D  ",
"D   D ",
"D  D  ",
"DDD   "
],        
[
"EEEEE ",
"E     ",
"EEEEE ",
"E     ",
"EEEEE "
],
[
"FFFFF ",
"F     ",
"FFFF  ",
"F     ",
"F     "
],            
[
"GGGGG ",
"G     ",
"G GGG ",
"G   G ",
"GGGGG "
],
[
"H   H ",
"H   H ",
"HHHHH ",
"H   H ",
"H   H "
],
[
" I  ",
" I  ",
" I  ",
" I  ",
" I  "
],
[
" JJJJ ",
"   J  ",
"   J  ",
"J  J  ",
"JJJJ  "
],
[
"K  K  ",
"K K   ",
"KK    ",
"K K   ",
"K  K  "
],
[
"L     ",
"L     ",
"L     ",
"L     ",
"LLLLL "
],
[
"MM MM ",
"M M M ",
"M   M ",
"M   M ",
"M   M "
],
[
"N   N ",
"NN  N ",
"N N N ",
"N  NN ",
"N   N "
],
[
"00000 ",
"O   O ",
"O   O ",
"O   O ",
"OOOOO "
],
[
"PPPPP ",
"P   P ",
"PPPP  ",
"P     ",
"P     "
],
[
"QQQQQ ",
"QQ  Q ",
"Q QQQ ",
"Q   Q ",
"QQQQ Q"
],
[
"RRRR  ",
"R   R ",
"RRRR  ",
"R R   ",
"R  R  "
],
[
"SSSSS ",
"S     ",
"SSSSS ",
"    S ",
"SSSSS "
],
[
"TTTTT ",
"  T   ",
"  T   ",
"  T   ",
"  T   "
],
[
"U   U ",
"U   U ",
"U   U ",
"U   U ",
"UUUUU "
],
[
"V   V ",
"V   V ",
"V   V ",
" V V  ",
"  V   "
],
[
"W   W ",
"W   W ",
"W   W ",
"W W W ",
"WW WW "
],
[
"X   X ",
" X X  ",
"  X   ",
" X X  ",
"X   X "
],
[
"Y   Y ",
" Y Y  ",
"  Y   ",
"  Y   ",
"  Y   "
],
[
"ZZZZZ ",
"   Z  ",
"  Z   ",
" Z    ",
"ZZZZZ "
]]

----------------------------------

draw :: String -> String
draw xs =  concatMap (\(i, xs)-> concatMap (\ x -> letterDatabase !! (ord (toUpper x) - 65) !! (i - 1)) xs ++ "\n") (zip [1..5] (replicate 5 xs))

main = putStrLn $ draw "GAB"

1 个答案:

答案 0 :(得分:3)

拍摄:

draw = unlines . map concat . Data.List.transpose
     . map ((letterDatabase !!) . subtract 65 . ord . toUpper)

编辑:好吧我猜我的原始镜头更像是高尔夫黑客而不是重构。这是使用Array轻微不易出错的版本(我想我可以使用关联列表来避免在Prelude之外使用更多函数,但不像Vector }和Map它至少在标准中。):

import Data.Char
import Data.Array
import Data.List

-- Again leaving out the letterDatabase for brevity, see question.

letterArray = listArray ('A','Z') letterDatabase

draw :: String -> String
draw = unlines . map concat . transpose
     . map (letterArray !)
     . filter (inRange $ bounds letterArray)
     . map toUpper

main = putStrLn $ draw "GAB"