How to refactor this code in Haskell

I made this simple code that draws letters on the terminal. How do I refactor this code using mostly Prelude functions? Other libraries can of course be used.

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"

      

+3


source to share


1 answer


Shooting:

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

      



EDIT: OK. I think my initial shot looks more like a golf hack than a refactoring. Here's a slightly less error prone version using Array

(I think I could use a list of associations to avoid using more functions outside Prelude

, but unlike Vector

and Map

at least in the standard.)

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"

      

+3


source







All Articles