2009-06-09 24 views
8

Các hiển thị chức năng trong Haskell dường như không làm những gì nó nên:Haskell: Hiển thị hơi say lên?

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


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

Khi tôi tuyên bố chức năng, tôi thường đặt chữ ký kiểu như Hiện, mà không đối phó với dòng mới đúng . Tôi muốn nó xử lý \n làm dòng mới, chứ không phải theo nghĩa đen "\n". Khi tôi thay đổi loại thành Chuỗi, các chức năng hoạt động tốt. Nhưng tôi sẽ phải thực hiện một chức năng riêng biệt cho các số nguyên, phao, vv, vv

Ví dụ, tôi có thể tuyên bố một chức năng:

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

... và gọi nó theo cách này:

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

Làm cách nào để nhận lại hàm được mong đợi? I E. chức năng nào tương tự như show nhưng có thể trả lại các chuỗi có chứa dòng mới?

+1

Bạn có thể cung cấp cho chúng tôi trường hợp sử dụng cụ thể về điều này không? Nó sẽ làm cho hiểu ý định của bạn dễ dàng hơn. – Martijn

+0

Bạn chỉ có thể thêm một kiểm tra để xem đầu vào có phải là một chuỗi không, và chỉ cần in nó. Kết hợp mẫu là một điều rất hữu ích. – Rayne

+1

"show" giống như 'repr()' trong Python và 'inspect' trong Ruby, nếu bạn đã sử dụng những ngôn ngữ đó trước đây. –

Trả lời

14

Hợp đồng của phương thức hiển thị trong Haskell là nó tạo ra một chuỗi, khi được đánh giá, mang lại giá trị được hiển thị.

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

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

Chỉ cần thêm vào điều này, chức năng bạn mô tả được gọi là "in" mà thực sự được xác định giống như trên in x = putStrLn (show x) – Phyx

3

show hiển thị biến theo cách bạn đã nhập.

Có vẻ khá thường xuyên với tôi.

9

Có vẻ như bạn đang cố gắng mô phỏng phương pháp ToString, mặc dù một số thuật ngữ của bạn là hơi khó hiểu.

Bạn có thể mô phỏng nó như thế này:

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

Tuy nhiên, như thể hiện bởi pragmas NGÔN NGỮ, đây không phải là rất đáng mơ ước. Để thực sự có được cảm giác về những gì bạn đang cố gắng làm điều đó sẽ dễ dàng hơn nếu chúng tôi có nhiều ngữ cảnh hơn ...

1

Tôi thực sự không chắc chắn về những gì bạn đang cố gắng làm. Nó sẽ giúp nếu bạn làm rõ một chút. Hiển thị đang làm những gì nó được cho là phải làm. Hiển thị chỉ đơn giản là tạo ra một chuỗi chứa những gì nó được hiển thị.

1

Kế hoạch của Porges hoạt động và tôi nghĩ nó sẽ đưa ra những gì show thực sự là do hành vi khó hiểu bạn tìm thấy trong ghci sẽ vẫn bật lên nếu bạn nhận được hàm IO mà bạn muốn. Lưu ý rằng tôi đã thêm một thể hiện cho mã Char to Porges, vì bạn có thể muốn không có dấu ngoặc kép.

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

sau đó, trong ghci, xem điều gì xảy ra với foo.show: "mà chức năng cũng tương tự như show nhưng có thể trở lại chuỗi có chứa ký tự dòng mới"

*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

Trả lời: id

+0

Bạn đang cố gắng trở thành vui hay bạn chỉ cần notr ead câu hỏi? – Jasper

+0

Điều này là khá cũ, nhưng có lẽ mattiast có nghĩa là "putStrLn $ id" ngăn xếp \ n \ noverflow "' mà trả lời câu hỏi. – stites

Các vấn đề liên quan