Haskell: Show screwed up?

前端 未结 6 503
小鲜肉
小鲜肉 2021-01-17 17:34

The show function in Haskell doesn\'t seem to do what it should:

Prelude> let str = \"stack\\n\\noverflow\"
Prelude> putStrLn str
stack


overfl         


        
相关标签:
6条回答
  • 2021-01-17 18:01

    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> 
    
    0 讨论(0)
  • 2021-01-17 18:10

    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...

    0 讨论(0)
  • 2021-01-17 18:13

    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.

    0 讨论(0)
  • 2021-01-17 18:17

    "which function is similar to show but can return strings containing newlines?"

    Answer: id

    0 讨论(0)
  • 2021-01-17 18:18

    show shows the variable in the way that you entered it.

    Seems pretty regular to me.

    0 讨论(0)
  • 2021-01-17 18:18

    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> 
    
    0 讨论(0)
提交回复
热议问题