2009-05-12 5 views
1

아래와 같이 문자열 목록을 출력하고 싶습니다.Haskell에서 'unwords'를 사용하여 문자열 목록을 인쇄하는 방법은 무엇입니까?

|Name|Country|Age| 
------------------ 
|1 |USA |20 | 
|2 |UK  |19 | 

다음을 사용하여이를 수행 할 수있었습니다.

printfieldName :: [String] -> String 
printfieldName [] = [] 
printfieldName (x:xs) = "|" ++ x ++ "\t" ++ printfieldName (xs) 

inbuilt 함수 'unwords'를 사용하여이를 수행 할 수 있습니까? 'unwords'를 사용하여 인쇄 할 수 있었지만 단어 사이에 |을 배치 할 수 없었습니다.

답변

4

'|'

printfieldName x = unwords (map ((++) "|") x) ++ "|" 

조금 설명 : 다음 map["|1", "|USA", "|20", ... ]

로 변환 단어 목록에이 기능을 적용

(++) "|" - creates a function which take prefixes each word with "|", so 
(++) "|" "test" -> "|test" 

다음 unwords 그들을 조인과 단어, 그래서 당신은이 기능을 사용할 수 있습니다 단어 사이에 공백이있는 문자열로 변환합니다. 추가하려면 ++ "|"이 필요합니다. |

+0

메신저 하스켈 할 새, 당신의 흐름을 설명해주십시오 수 함수가 작성되었습니다. 그것은 작동합니다!:) 감사합니다 – pier

+0

쿨! (++) "|" 각 단어 앞에 "|"가 붙는 함수를 만듭니다. 그래서 (++) "|" "test"-> "test" 'map '은 [ "| 1", "| USA", "| 20"...]로 변환하는 단어 목록에이 함수를 적용합니다. then 'unwords '는 그들을 단어들 사이에 공백이있는 문자열로 결합시킵니다. '++ '|' '는 마지막 | –

+0

죄송합니다. 덧글의 모든 줄 바꿈이 손실되었습니다. 나는 여기에서 새로운 것이다 : –

4

첫째,이처럼 작성합니다

printfieldName []  = [] 
printfieldName (x:xs) = "|" ++ x ++ "\t" ++ printfieldName xs 

음, 사실, 아니,이 같은 :

concatMap (\x -> '|' : x ++ "\t") 

음, 어쩌면 같은 :

concatMap (printf "|%s\t") 

OK . 그럼 'unwords'로 할 수 있습니까?

-- | 'unwords' is an inverse operation to 'words'. 
-- It joins words with separating spaces. 
unwords     :: [String] -> String 
unwords []    = "" 
unwords ws    = foldr1 (\w s -> w ++ ' ':s) ws 

호 그러나 당신이 foldr로 concatMap을 쓸 수 있는지 ... 내가 추가 공간 사이가 볼

+0

지금이 권리를 시도, 난 때 오류가 나는 실행 구문 오류 (예기치 않은 백 슬래시 (lambda)) printfieldName :: [문자열] -> 문자열 printfieldName [] = [] concatMap (\ X -> '|'X ++ "\의 t을") concatMap (printf와 "| %의 \ t") 감사 – pier

+0

은 더 많은 정보를 서곡 Text.Printf> putStrLn $ concatMap 필요 @dlna (printf와 "| %의 \ t") (지도 ([]) "안녕하세요") | 시간 \t | 전자 ​​\t | 리터 \t | 리터 \t | 오 –

4

Data.List에는 intersperse라는 기능이 있습니다. 아마 당신은 그것을 사용할 수 있습니다.

printfieldName xs = "|" ++ unwords (intersperse "|\t" xs) ++ "|" 
1

아마도 당신이 무엇을 요구에서 맨 위에 작은, 그러나 :

formatTable :: [String] -> [[String]] -> String 
formatTable header rows = 
    formatRow header ++ dashRow ++ concatMap formatRow rows 

    where formatRow cells = bracket '|' (spread cells) 
      dashRow   = bracket '+' (map (\n -> replicate n '-') widths) 
      bracket c cells = concatMap (c:) cells ++ (c:"\n") 

      spread cells = zipWith pad widths cells 
      pad n s   = take n (s ++ repeat ' ') 

      widths = foldr maxLengths (repeat 0) (header : rows) 
      maxLengths = zipWith (\c l -> max (length c) l) 

그리고, 예를 들면 :

> let h = words "Name Country Age" 
> let rows = map words ["1 USA 20", "2 UK 19"] 
> h 
["Name","Country","Age"] 
> rows 
[["1","USA","20"],["2","UK","19"]] 
> putStr $ formatTable h rows 
|Name|Country|Age| 
+----+-------+---+ 
|1 |USA |20 | 
|2 |UK  |19 | 
관련 문제