在haskell中键入错误

时间:2015-02-24 22:38:32

标签: string list haskell types integer

我在this tutorial之后的几个小时内开始学习haskell。尝试编译以下代码时,我不断收到Couldn't match type错误:

module Main where
import Control.Monad

main = do
    putStrLn "Enter child age"
    input <- getLine
    -- convert the string to int
    let age = read input :: Int
    unless (age == 0) $ do
        -- let ages = []
        -- print age
        -- add child age to list here?
        ages ++ [age]
        main

这是错误:

Couldn't match type `IO' with `[]'                                                                         
Expected type: [()]                                                                                        
  Actual type: IO () 

我一直在寻找几个小时试图理解这个问题,但没有任何线索。为什么ages ++ [age2]需要IO Int类型?以及如何解决这个问题?

更新:ages是一个列表,其中包含两个孩子的年龄。它将在未来使用。还创建了循环

2 个答案:

答案 0 :(得分:2)

ages ++ [age1]ages ++ [age2]是导致[Int]的表达式。他们不会修改ages; ages只是一个价值。由于您根本没有使用ages,因此一个非常简单的解决办法就是将所有三行都删除:

let ages = []
ages ++ [age1]
ages ++ [age2]
如果您要将其用作ages,则可以在age1age2之后构建

[age1, age2]。如果你想使用一个列表不重复自己,你可能会在Haskell的这些方面做更多的事情:

readAge :: String -> IO Int
readAge prompt = do
    putStrLn prompt
    readLn :: IO Int

main = do
    ages <- mapM readAge ["Enter child 1 age", "Enter child 2 age"]
    print ages

要在循环中执行此操作,您可以从:

开始
readAges :: IO [Int]
readAges = do
    putStrLn "Enter child age"
    age <- readLn :: IO Int

    if age == 0 then
        return []
    else
        fmap (age:) readAges

main :: IO ()
main = do
    ages <- readAges
    print ages

fmap (age:) readAges的缩写:

ages <- readAges
return $ age : ages

答案 1 :(得分:0)

在Haskell中,变量是不可变的。你可能正在寻找更像这样的东西:

inputAges :: [Int] -> IO [Int]
inputAges (0:otherAges) = return otherAges
inputAges ages          = _

此递归函数在其参数中跟踪年龄。定义的第一行检查最新阅读年龄是否为0。如果是这样,它会返回除0之外的所有内容。如果列表具有至少一个元素且其头部为(0:otherAges),则列表将匹配模式0。如果匹配,则尾部绑定到otherAges。否则,它将进入下一个模式(此处为下一行)。

我离开了递归案例,但我可以给予更多帮助。您需要读取年龄的内容,并使用具有新年龄的列表调用自身。部分阅读与您问题中的代码看起来大致相同。