The show function in Haskell doesn\'t seem to do what it should:
Prelude> let str = \"stack\\n\\noverflow\"
Prelude> putStrLn str
stack
overfl
The contract of the show method in Haskell is that it produce a string that, when evaluated, yields the value that was shown.
Prelude> let str = "stack\n\noverflow"
Prelude> putStrLn str
stack
overflow
Prelude> putStrLn (show str)
"stack\n\noverflow"
Prelude>
Sounds like you're trying to simulate a ToString method, although some of your terminology is a little confusing.
You can simulate it like this:
{-# LANGUAGE UndecidableInstances, OverlappingInstances,
FlexibleInstances, TypeSynonymInstances #-}
class ToString a where
toString :: a -> String
instance ToString String where
toString = id
instance Show a => ToString a where
toString = show
However, as shown by the LANGUAGE pragmas, this is not very desirable. To really get a feel for what you're trying to do it would be easier if we had more context...
I'm not really sure the point in what your trying to do. It would help if you clarified a bit. Show is doing what it is supposed to do. Show simply produces a string containing what it was shown.
"which function is similar to show
but can return strings containing newlines?"
Answer: id
show
shows the variable in the way that you entered it.
Seems pretty regular to me.
Porges' plan works and I think it brings out brings out what show
is really up to, since the confusing behavior you found in ghci will still turn up if you get the IO function you want. Note that I added an instance for Char to Porges' code, since you would presumably want that not to have quotes.
{-# LANGUAGE UndecidableInstances, OverlappingInstances,
FlexibleInstances, TypeSynonymInstances #-}
class ToString a where
toString :: a -> String
instance ToString String where
toString = id
instance ToString Char where
toString x = [x]
instance Show a => ToString a where
toString = show
foo :: (ToString a) => a -> IO ()
foo x = do {putStrLn $ toString x}
then, in ghci, watch what happens with foo.show
:
*Main> let str = "stack\n\noverflow"
*Main> show str
"\"stack\\n\\noverflow\""
*Main> putStrLn str
stack
overflow
*Main> putStrLn (show str)
"stack\n\noverflow"
*Main> foo str
stack
overflow
*Main> foo (show str)
"stack\n\noverflow"
*Main> foo ( show (show str))
"\"stack\\n\\noverflow\""
*Main> let newl = "\n"
*Main> foo newl
*Main> putStrLn newl
*Main> putStrLn (show newl)
"\n"
*Main> foo (show newl)
"\n"
*Main> foo (show (show newl))
"\"\\n\""
*Main>