2017-02-25 44 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