哈斯克尔:显示搞砸了?

时间:2009-06-09 04:52:07

标签: api haskell

Haskell中的 show 函数似乎没有做它应该做的事情:

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


overflow
Prelude> show str
"\"Stack\\n\\n\\noverflow\""
Prelude>

当我声明函数时,我通常将类型签名设置为显示,它不能正确处理换行符。我希望它将\n视为换行符,而非字面"\n"。当我将类型更改为 String 时,函数可以正常工作。但是我必须为整数,浮点数等实现一个单独的函数。

例如,我可以声明一个函数:

foo :: (Show x) => x -> IO ()
foo x = do
  putStrLn $ show x

...并以这种方式称呼它:

foo "stack\n\noverflow"
foo 6
foo [1..]

如何让函数返回预期的函数?即哪个函数类似于show但可以返回包含换行符的字符串?

6 个答案:

答案 0 :(得分:14)

Haskell中show方法的契约是它生成一个字符串,在计算时会产生显示的值。

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

overflow
Prelude> putStrLn (show str)
"stack\n\noverflow"
Prelude> 

答案 1 :(得分:9)

听起来你正试图模拟一个ToString方法,尽管你的一些术语是 有点混乱。

您可以像这样模拟它:

{-# 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

但是,如LANGUAGE编译指示所示,这不是很理想。要真正了解你想要做的事情,如果我们有更多的背景会更容易......

答案 2 :(得分:3)

show以您输入的方式显示变量。

对我而言似乎很正常。

答案 3 :(得分:1)

我不确定你要做什么的重点。如果你澄清了一点会有所帮助。秀正在做它应该做的事情。 Show只会生成一个包含所显示内容的字符串。

答案 4 :(得分:1)

Porges的计划有效,我认为它带出了show真正的意义,因为如果你得到你想要的IO功能,你在ghci中发现的混乱行为仍然会出现。请注意,我为Char to Porges的代码添加了一个实例,因为您可能希望不要有引号。

{-# 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}

然后,在ghci中,观察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> 

答案 5 :(得分:0)

“哪个函数类似于show但可以返回包含换行符的字符串?”

答案:id