2009-06-09 93 views
8

显示似乎在Haskell功能并没有做自己应该:Haskell:显示搞砸了?

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


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

当我宣布的功能,我通常把类型签名,显示,这不换行正确处理。我希望它将\n视为换行符,而不是字面上的"\n"。当我将类型更改为字符串时,这些功能正常工作。但我不得不执行一个单独的功能为整数,浮点数,等等,等等

例如,我可以声明函数:

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

...并调用它是这样的:

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

我将如何获得函数来返回所期望的?即该函数与show类似,但可以返回包含换行符的字符串?

+1

你能给我们一个具体的用例吗?这会让你更容易理解你的意图。 – Martijn 2009-06-09 09:58:38

+0

您可以添加一个检查来查看输入是否是一个字符串,然后将其打印出来。模式匹配是一个非常有用的事情。 – Rayne 2009-06-09 15:01:54

+1

如果您以前使用过这些语言,则“show”就像Python中的repr()和Ruby中的“inspect”。 – 2011-12-12 20:55:25

回答

14

Haskell中show方法的契约是它生成一个字符串,当它被评估时,它会产生显示的值。

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

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

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

似乎很规律的给我。

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 

然而,如由语言编译指示,这是不是非常理想。如果我们有更多的上下文,要真正了解你想要做的事情会更容易...

1

我不确定你想要做什么。如果你澄清一点,这将有所帮助。 Show正在做它应该做的事情。 Show只是产生一个包含它所显示内容的字符串。

1

Porges的计划工作,我认为它带来了什么show是真正的,因为你在ghci中找到的混淆行为仍然会出现,如果你得到你想要的IO功能。请注意,我为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: “它的功能类似于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>