Haskell:无法编译程序

时间:2011-11-07 10:51:33

标签: haskell

我无法编译以下代码:

main = do 
  line <- getLine
  putStrLn (work (toInt line) [0,0,0])

work n b = do
  if n == 0 
    then 
        unwords (map show b)
    else do 
        line <- getLine
        work n-1 summ (map toInt . unwords line) b

toInt :: String -> Int
toInt b = read b

toInts a = map toInt a

summ [] [] = []
summ (x:xs) (y:ys) = (x+y) ++ (summ xs ys)

这是错误:

src\Main.hs:28:21:
Couldn't match expected type `[t0]' with actual type `IO String'
In a stmt of a 'do' expression: line <- getLine
In the expression:
  do { line <- getLine;
         work n - 1 summ (map toInt . unwords line) b }
In the expression:
  if n == 0 then
      unwords (map show b)
  else
      do { line <- getLine;
             work n - 1 summ (map toInt . unwords line) b }

我对该计划的期望是阅读

n
a1 b1 c1
a2 b2 c2
...
a_n b_n c_n

和输出

sum(a) sum(b) sum(c)

你能否解释为什么getLine的出现是好的,但以下不是?

EDIT1

我修改了工作函数如下:

work :: Int -> [Int] -> String
work n b = do
if n == 0 
    then 
        return $ unwords (map show b)
    else do 
        line <- getLine
        work (n-1) (summ toInts.words line b)

现在的错误是:

src\Main.hs:27:13:
Couldn't match expected type `Char' with actual type `[Char]'
Expected type: String
  Actual type: [String]
In the expression: return $ unwords (map show b)
In the expression:
  if n == 0 then
        return $ unwords (map show b)
  else
      do { line <- getLine;
           work (n - 1) (summ toInts . words line b) }

EDIT2 的 这是最后的工作进展:

main = do 
line <- getLine
ans <- (work (toInt line) [0,0,0])
putStrLn ans

work 0 b = return $ unwords (map show b)
work n b = do
line <- getLine
work (n-1) $ zipWith (+) (map toInt (words line)) b

toInt b = read b::Int

2 个答案:

答案 0 :(得分:3)

似乎work不在IO monad中:您可以通过将if语句的then部分读为return $ unwords (map show b)来解决此问题。< / p>

明确的类型签名是对Haskell编程的一个极其有用的帮助:虽然从技术上讲它不需要它们,但是一个非常常见的工作流程是:

  1. 指定
  2. 的函数类型
  3. 添加定义
  4. 尝试将文件加载到ghci
  5. 修复可能发生的任何类型错误。
  6. EDIT1

    与原始问题中的编辑匹配的版本是:

    work :: Int -> [Int] -> IO String
    work n b = do
      if n == 0 
        then 
            return $ unwords (map show b)
        else do 
            line <- getLine
            work (n-1) $ summ (map toInts $ words line) b
    

    改进的变体是:

    work :: Int -> [Int] -> IO String
    work 0 bs = return . unwords $ map show bs
    work n bs = do line <- getLine
                   work (n-1) $ summ (map toInts $ words line) b
    

    另请注意,summ的定义不正确,因为它使用++时应使用:(实际上与zipWith (+)相同)。

答案 1 :(得分:0)

你有

work n b = do
  if n == 0 
    then 
        unwords (map show b)
    else do 
        line <- getLine
        work n-1 summ (map toInt . unwords line) b

最后一行应该是

        work (n-1) (summ (map toInt . unwords line) b)

请注意额外的括号。

也可能存在其他错误。