2009-05-05 16 views
4

基本的には、タイプ[(String, String)]のリストを取り込んで出力を出力するような関数を書くことです。出力は次のようになります。これは:Haskell:タプルのリストの内容を出力する

FirstString : SecondString 

FirstString : SecondString 

..etc、リスト内のすべての項目についてです。私は次のコードを持っているし、それを印刷しますが、何らかの理由で最後に[(),()]を含む行を出力します。

display :: Table -> IO() 
display zs = do { 
    xs <- sequence [putStrLn (a ++ " = " ++ b) | (a, b) <- zs]; 
    print xs 
} 

私が間違っていることはありますか?

答えて

10

最後の印刷xsは不要です。ここでは、一連のof()s(putStrLnの戻り値)を返しています。printはそれを同様に出力しています。

display :: Table -> IO() 
display zs = sequence_ [putStrLn (a++" = "++b) | (a,b) <- zs] 
+2

メモリが気になる場合は、newacctの方法(下記)をチェックしてください。 –

4

書き込み:あなたはそれに取り組んでいる一方で、今では印刷XSがなくなって

、あなたが与え、XS変数バインディングを取り除き、および戻り値を捨ててsequence_のに列を作る得ることができますあなたが望むようにフォーマットされた文字列にタプルをとる関数。
その後、concatMapはあなたのリスト上で機能します。結果を印刷します。あなたもmapMを使用することができます

8

display :: Table -> IO() 
display = mapM_ (\(a,b) -> putStrLn (a++" = "++b)) 
+1

このメソッドは、bdonlanのメソッドよりも少ないメモリを使用します。私のサンプルデータでは、この方法では約70k以下でした。私はbdonlanのメソッドがIOアクションのリストを作成しなければならなかったので、より多くのメモリを使用したのだろうかと思います。 –

+1

どのようにメモリ使用量を測定していますか? Haskellは一時的な割り当ての/ lot /を作成するので、おそらくこれはちょっと高速です:) – bdonlan

6

私は、あなたは2つの機能へのあなたのコードを分割する必要があり、JAに同意するだろう:

  • 純粋一部:とる関数あなたのデータ構造体を文字列に変換する
  • 不純な部分は、その文字列をコンソールにレンダリングします

はここで単純な実装です:

showTable :: Table -> String 
showTable xs = concatMap format xs 
    where 
    format (a, b) = a ++ " : " ++ b ++ "\n" 

display :: Table -> IO() 
display table = putStr (showTable table) 

この設計は、2つの利点があります。

一つは、あなたの `ロジック」のほとんどがいいですコードの純粋な一部であり、関数型プログラミングのように。

第2に、これは単純なソフトウェア工学の原理です。コードの別の部分にデータ構造を書式設定する必要がある場合(おそらく)、再利用可能な関数を使用できるようになりました。

+1

またはShow typeclassのTable部分を作成します。そのためには、次のようにします: 'show myTable' – fengshaun

関連する問題