首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >putStrLn,字符类型与[字符]不匹配

putStrLn,字符类型与[字符]不匹配
EN

Stack Overflow用户
提问于 2010-06-04 16:43:34
回答 1查看 695关注 0票数 1

我有一个haskell的问题。putStrLn应该接受一个字符或字符串,尽管我似乎把它交给了Compiler先生,但他仍然抱怨。

代码语言:javascript
运行
复制
*** Expression     : putStrLn line
*** Term           : line
*** Type           : Char
*** Does not match : [Char]

它引用的代码是这样的:

代码语言:javascript
运行
复制
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的参数。那么问题出在哪里?:/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-06-04 16:46:45

由于getS返回的是String,而不是IO String,因此不需要使用<-“提取”纯值。

只需使用

代码语言:javascript
运行
复制
do
  let line = getS x
  putStrLn line
  getV xs

此外,还有一个mapM function,您可以

代码语言:javascript
运行
复制
getV xs = mapM (putStrLn.getS) xs

而且你的getS不必要地使用了monads。

代码语言:javascript
运行
复制
getS [] = ""
getS ((c,_):str) = "(L" ++ [c] ++ ")" ++ getS str

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

代码语言:javascript
运行
复制
getS ps = concatMap (\(c,_) -> "(L" ++ [c] ++ ")") ps

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

代码语言:javascript
运行
复制
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.

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

代码语言:javascript
运行
复制
cartesian xs ys = [(x, y) | x <- xs, y <- ys]
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2972613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档