Reputation: 3
I am a beginner in haskell, please, tell me what I am doing wrong.
newtype (Matrix a) = Matr [[a]]
instance Show (Matrix a) where
show (Matr d) = print d
where print [] = []
print (x:xs) = show x ++ "\n" ++ print xs
No instance for (Show a) arising from a use of `print'
Possible fix:
add (Show a) to the context of the instance declaration
Upvotes: 0
Views: 471
Reputation: 15967
The error message says "you need a Show
instance for the element type of your matrix".
Also print
is the wrong function to call here - show
is equivalent to toString
in languages like java - whereas print
is an IO-operation that puts a String
to stdout, you are using a name that has already a meaning.
newtype Matrix a = Matr [[a]]
instance Show a => Show (Matrix a) where
show (Matr xx) = showlines xx
where showlines [] = ""
showlines (x:xs) = showelems x ++ "\n" ++ showlines xs
showelems [] = ""
showelems (x:xs) = show x ++ " " ++ showelems xs
now this showline
/showelems
pattern is already a common one the functions are unlines
and unwords
but the elements need to be strings already so
show (Matr xx) = let strs = map (map show) xx
in unlines $ map unwords xx
or a bit terser
show (Matr xx) = unlines $ map (unwords . map show) xx
here is some example usage of unlines
/unwords
$ > ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> putStrLn $ unlines ["a","b"]
a
b
Prelude> putStrLn $ unlines $ map unwords [["a","b"],["c","d"]]
a b
c d
Prelude> putStrLn $ unlines $ map (unwords . map show ) [[1,2],[3,4]]
1 2
3 4
@lisyarus' answer shows a lot more what happens behind the scene - but note the output of that show function is different from mine.
Prelude> import Data.List
Prelude Data.List> putStrLn $ concat . intersperse "\n" . map show $ [[1,2],[3,4]]
[1,2]
[3,4]
Upvotes: 3
Reputation: 15522
print (x:xs) = show x ++ "\n" ++ print xs
Here, x
has type [a]
. The instance Show [a]
needs an instance of Show a
. In other words, you have to tell how to show a
in order to be able to show [a]
.
Add a dependency on Show a
in your instance declaration:
instance (Show a) => Show (Matrix a) where
...
By the way, your code can be written using standard library like this:
show (Matr d) = concat . intersperse "\n" . map show $ d
Note: You need to import Data.List
in your matrix module for the intersperse
function!
Upvotes: 2