Show instance for matrix in Haskell

两盒软妹~` 提交于 2019-12-31 05:23:11

问题


I've been trying to create a show instance in order to visualize a given matrix and also, to create an outline with columns around and in between the matrix. What I managed to accomplish so far is the following:

data Mat a = Mat [[a]]
instance (Show a) => Show (Mat a) where
show (Mat x) = "\n" ++ " ---\n"++unlines ( map (\r -> showRow r ++ "\n ---") x ) ++ "\n"
    where
      showRow list = "¦ "++unwords ( map (\v -> show v ++" ¦") list)

Assuming we have a matrix Mat [[1,2,3],[4,5,6]] that we would like to test.

The output from the command line is the following:

 ---
¦ 1 ¦ 2 ¦ 3 ¦
 ---
¦ 4 ¦ 5 ¦ 6 ¦
 ---

What I would like to achieve is to format the given matrix with horizontal lines above the rest of each column, like that:

 --- --- ---
¦ 1 ¦ 2 ¦ 3 ¦
 --- --- ---
¦ 4 ¦ 5 ¦ 6 ¦
 --- --- ---

回答1:


If you make the assumptions that all rows of a matrix have the same number of columns (or at least that the first row of any matrix has at least as many columns as any other), and that three dashes suffice as the border for any cell, you can calculate the number of dashes to use between rows by taking the length of the leading row.

If these assumptions do not hold, you need to make one pass over the array to calculate the maximum width of any row, then a second pass to draw the matrix. If matrices can contain numbers outside the range [0..9], you would also need to calculate the width of each column.

The algorithm might be:

  1. Map each number in the matrix to a String, generating a [[String]].
  2. Generate a list of column widths, whose elements are the maximum width of any row’s element in that column.
  3. Left-pad every string in the [[String]] with spaces to its column width.
  4. Concatenate the columns of each row, adding the appropriate separator between elements and the appropriate left and right borders. The result is a [String] whose elements are the graphical representation of each row.
  5. If you wish to add horizontal rules above, below, or between the rows, take the length of any element of the [String] (As all columns are now padded to their maximum width, all rows should now have the same length.) and generate that number of box-drawing characters, such as ASCII "---" or Unicode "┌─┬─┐".
  6. Concatenate the rows and the separator lines into a String separated by newlines.

As Rein Henrichs mentioned in a comment, you might consider naming this function something other than show.



来源:https://stackoverflow.com/questions/44216339/show-instance-for-matrix-in-haskell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!