2017-02-25 26 views
0

我嘗試使用\n,putStrLnprint,但沒有任何工作。我如何在Haskell上劃線?

當我使用\n時,結果僅連接字符串,並且當我使用putStrLnprint時,我收到一個類型錯誤。

輸出爲\n

formatLines [("a",12),("b",13),("c",14)] 
"a...............12\nb...............13\nc...............14\n" 

輸出爲putStrLn

format.hs:6:22: 
    Couldn't match type `IO()' with `[Char]' 
    Expected type: String 
     Actual type: IO() 
    In the return type of a call of `putStrLn' 
    In the expression: 
     putStrLn (formatLine ((fst x), (snd x)) ++ formatLines xs) 
    In an equation for `formatLines': 
     formatLines (x : xs) 
      = putStrLn (formatLine ((fst x), (snd x)) ++ formatLines xs) 
Failed, modules loaded: none. 

輸出爲print是相同的putStrLn

這裏是我的代碼:

formatLine :: (String,Integer) -> String 
formatLine (s, i) = s ++ "..............." ++ show i 

formatLines::[(String,Integer)] -> String 
formatLines [] = "" 
formatLines (x:xs) = print (formatLine ((fst x), (snd x)) ++ formatLines xs) 

我理解錯誤了printputStrLn的原因,但我不知道如何解決它。

回答

5

將代碼分爲兩部分。

一部分簡單地構造字符串。換行符使用"\n"

第二部分採用該字符串並將putStrLn(不是print)應用於它。換行符將被正確打印。

例子:

foo :: String -> Int -> String 
foo s n = s ++ "\n" ++ show (n*10) ++ "\n" ++ s 

bar :: IO() 
bar = putStrLn (foo "abc" 42) 
    -- or putStr (...) for no trailing newline 

baz :: String -> IO() 
baz s = putStrLn (foo s 21) 

如果使用print,則系統會打印字符串表示,股價和它裏面逃逸(如\n)。僅對必須轉換爲字符串的值使用print,如數字。

另請注意,您只能在返回類型爲IO (something)的函數中執行IO(如打印內容)。

+0

我沒有完全理解。 bar的返回值是IO()並且沒有輸入,但是如果我希望將參數傳遞給bar函數?因爲我需要指定輸入。例如'bar s i = putStrLn(foo s i)'? – Marcio

+1

@Marcio你可以添加額外的參數。你的例子中的'bar'將有'bar :: String - > Int - > IO()'類型。 – chi

+0

非常感謝你!但我有更多的疑問:存在某種方式來連接條的結果與一個字符串?我試着用'show',做這樣的事情:''hello「++(show baz s)',但沒有奏效。出現一條消息「由於使用」show「引起的(Show(IO())的實例),我不知道可能是什麼樣的節目。我很抱歉,如果我利用你 – Marcio

1

您需要打印輸出的結果。

這是一個IO操作,所以你不能有一個以-> String結尾的函數簽名。相反,正如@chi指出的那樣,返回類型應該是IO()。此外,由於您已經具有生成格式化字符串的功能,所有您需要的功能都是幫助您將打印操作映射到輸入列表上。這可以做使用mapM_,就像這樣:

formatLines::[(String,Integer)] -> IO() 
formatLines y = mapM_ (putStrLn . formatLine) y 

Demo