0

I'm having trouble printing contents of a custom matrix type I made. When I try to do it tells me

 Ambiguous occurrence `show'
 It could refer to either `MatrixShow.show',
                          defined at Matrices.hs:6:9
                       or `Prelude.show',
                          imported from `Prelude' at Matrices.hs:1:8-17

Here is the module I'm importing:

module Matrix (Matrix(..), fillWith, fromRule, numRows, numColumns, at, mtranspose, mmap) where
newtype Matrix a = Mat ((Int,Int), (Int,Int) -> a)

fillWith :: (Int,Int) -> a -> (Matrix a)
fillWith (n,m) k = Mat ((n,m), (\(_,_) -> k))

fromRule :: (Int,Int) -> ((Int,Int) -> a) -> (Matrix a)
fromRule (n,m) f = Mat ((n,m), f)

numRows :: (Matrix a) -> Int
numRows (Mat ((n,_),_)) = n

numColumns :: (Matrix a) -> Int
numColumns (Mat ((_,m),_)) = m

at :: (Matrix a) -> (Int, Int) -> a
at (Mat ((n,m), f)) (i,j)| (i > 0) && (j > 0) || (i <= n) && (j <= m) = f (i,j)

mtranspose :: (Matrix a) -> (Matrix a)
mtranspose (Mat ((n,m),f)) = (Mat ((m,n),\(j,i) -> f (i,j)))

mmap :: (a -> b) -> (Matrix a) -> (Matrix b)
mmap h (Mat ((n,m),f)) = (Mat ((n,m), h.f))

This is my module:

module MatrixShow where
    import Matrix


    instance (Show a) => Show (Matrix a) where 
    show (Mat ((x,y),f)) = show f

Also is there some place where I can figure this out on my own, some link with instructions or some tutorial or something to learn how to do this.

7
  • As far as figuring this out on your own, you should have gotten a warning with this code in the form of No explicit implementation for either 'showsPrec' or 'Prelude.show' which is something that should tip you off. And there are many tutorials and non-interactive resources including yet another haskell tutorial, A Gental Introduction, Learn you a Haskell, a dozen books, etc. Commented Oct 19, 2015 at 21:25
  • I will look for them, but it is really difficult to learn this stuff when the person who gives you this stuff simply throws it at you and doesn't explain anything about it, which is what is happening now. They gave us this, they told us nothing, and now somehow we're supposed to figure it out. Commented Oct 19, 2015 at 21:31
  • 2
    So is this a class? If so I recommend you talk to the instructor. Also, hang out on #haskell at irc.freenode.net. Commented Oct 19, 2015 at 21:56
  • I'm not exactly sure, I'm guessing that what he did was to override the current Matrix type that exists for Haskell along with those methods. Now what he wants us to do is to display the matrix row by row. Normally I'd say that's not so difficult to do, but there's an issue I'm not sure about which is how is the matrix built, whether that is with a vector or a 2D array. If I knew I could solve this easily, I've already done it with a 2D array but yeah, he never explained anything. Commented Oct 19, 2015 at 22:08
  • 2
    @Argus To play Devil's Avocado: you're confused about whether the matrix is represented by "a vector or a 2D array". Are you certain that those are the only two ways a matrix can be represented? Have a careful read of the code your instructor has supplied to you. newtype Matrix a = Mat ((Int,Int), (Int,Int) -> a) doesn't look like a 2D array to me... Commented Oct 19, 2015 at 22:20

2 Answers 2

4

The problem is with your indentation. The definition of show needs to be indented relative to the instance show a => Show (Matrix a). As it is, it appears that you are trying to define a new function called show, unrelated to the Show class, which you can't do.

Sign up to request clarification or add additional context in comments.

Comments

2

@dfeuer, whose name I continue to have trouble spelling, has given you the direct answer - Haskell is sensitive to layout - but I'm going to try to help you with the underlying question that you've alluded to in the comments, without giving you the full answer.

You mentioned that you were confused about how matrices are represented. Read the source, Luke:

newtype Matrix a = Mat ((Int,Int), (Int,Int) -> a)

This newtype declaration tells you that a Matrix is formed from a pair ((Int,Int), (Int,Int) -> a). If you split up the tuple, that's an (Int, Int) pair and a function of type (Int, Int) -> a (a function with two integer arguments which returns something of arbitrary type a). This suggests to me that the first part of the tuple represents the size of the matrix, and the second part is a function mapping coordinates onto elements. This hypothesis seems to be confirmed by some of the example code your professor has given you - have a look at at or mtranspose, for example.

So, the question is - given the width and height of the matrix, and a function which will give you the element at a given coordinate, how do we give a string showing the items in the matrix?

The first thing we need to do is enumerate all the possible coordinates for the given width and height of the matrix. Haskell provides some useful syntactic constructs for this sort of operation - we can write [x .. y] to enumerate all the values between x and y, and use a list comprehension to unpack those enumerations in a nested loop.

coords :: (Int, Int)  -- (width, height)
          -> [(Int, Int)]  -- (x, y) pairs
coords (w, h) = [(x, y) | x <- [0 .. w], y <- [0 .. h]]

For example:

ghci> coords (2, 4)
[(0,0),(0,1),(0,2),(0,3),(0,4),(1,0),(1,1),(1,2),(1,3),(1,4),(2,0),(2,1),(2,2),(2,3),(2,4)]

Now that we've worked out how to list all the possible coordinates in a matrix, how do we turn coordinates into elements of type a? Well, the Mat constructor contains a function (Int, Int) -> a which gives you the element associated with a single coordinate. We need to apply that function to each of the coordinates in the list which we just enumerated. This is what map does.

elems :: Matrix a -> [a]
elems (Mat (size, f)) = map f $ coords size

So, there's the code to enumerate the elements of a matrix. Can you figure out how to modify this code so that a) it shows the elements as a string and b) it shows them in a row-by-row fashion? You'll probably need to adjust both of these functions.


I suppose the broader point I'd like to make is that even though it feels like your professor has thrown you into the deep end, it's always possible to do a little detective work and figure out for yourself what something means. Many - most? - of the people answering questions on this site are self-taught programmers, myself included. We persevered!

After all, it's just code. If a computer's going to understand it then it must be written down on the page, and that means that you can understand it, too.

4 Comments

I understand what you mean, usually I do investigate this sorts of things but Haskell is uncharted territory for me, I did search for tutorials and stuff, but I had a lot of trouble doing the most basic of things. Thanks for the help, I found out that this is being implemented through ordered pairs. I think I can come up with something here to print this thing. Thanks again.
I can recommend Learn You A Haskell as an introductory study guide to help you get used to the language. It's one of my favourite programming books.
Would it be easier to remember that my name is David Feuer? Or דוד פוייר? Perhaps I should have called myself treeowl here as I do on GitHub....
@dfeuer For some reason I always want to add an E between the D and the F. I have no idea why I find it so difficult, especially when it's written down right in front of me :S

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.