【问题标题】:putStrLn, type Char does not match [Char]putStrLn, 类型 Char 不匹配 [Char]
【发布时间】:2011-02-27 16:38:54
【问题描述】:

我有一个haskell 问题。 putStrLn 应该接受一个 [Char] 或一个字符串,即使我把它交给了 Compiler 先生,他仍然抱怨。

*** Expression     : putStrLn line
*** Term           : line
*** Type           : Char
*** Does not match : [Char]

它引用的代码是这样的:

getV::[[(Char,Float)]] -> IO ()
getV [] = putStrLn ""
getV (x:xs) = do line <- getS x
   putStrLn line      <-- Complaining line
   getV xs

getS::[(Char,Float)] -> String
getS [] = ""
getS ((c,f):str) = do a <- "(L" ++ [c] ++")" ++ getS str
    return a

我确实将它剥离了一点,但它应该是完全相同的行为。 getS 确实返回一个字符串,该字符串是 putStrLn 的参数。那么问题是什么? :/

【问题讨论】:

  • 只是一些格式化建议:您的代码格式错误,无法在 GHC 中运行。尝试将每一行与上面的行对齐(这样putStrLn linep 就在line &lt;- getS xl 的正下方。另外,如果你有-- Complaining line 并离开@987654328,那就太好了@,所以这是一个合法的评论,人们可以复制粘贴你的代码。
  • 是的,你说的是实话 :D 下次我会更好
  • 这次为什么不能做得更好?您可以随时返回并编辑您的问题! (另外,+1 以幽默的方式接受我的挑剔:) 祝你的 Haskelling 好运!)

标签: haskell functional-programming io


【解决方案1】:

由于您的getS 返回的是String,而不是IO String,因此无需使用&lt;-“提取”纯值。

随便用

do
  let line = getS x
  putStrLn line
  getV xs

另外,您可以使用mapM function

getV xs = mapM (putStrLn.getS) xs

而您的 getS 正在不必要地使用 monad。

getS [] = ""
getS ((c,_):str) = "(L" ++ [c] ++ ")" ++ getS str

当然,也可以只使用内置函数来编写。

getS ps = concatMap (\(c,_) -> "(L" ++ [c] ++ ")") ps

您的代码在line &lt;- getS x 行上没有失败,并且line 变成Char 的原因是因为List 也是一个monad。例如,我们可以将笛卡尔积写为

cartesian :: [a] -> [b] -> [(a,b)]
cartesian xs ys = do
    x <- xs    -- # Now x is of type 'a', representing any element in xs
    y <- ys    -- # Now y is of type 'b', representing any element in ys
    return (x, y) -- # Return the tuple composed of any elements in xs and ys.

事实上,列表推导是基于列表的这种一元属性。

cartesian xs ys = [(x, y) | x <- xs, y <- ys]

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多