【问题标题】:Type errors in haskell在haskell中输入错误
【发布时间】:2015-04-26 18:46:49
【问题描述】:

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 是一个包含两个孩子年龄的列表。将来会用到。还创建了循环

【问题讨论】:

    标签: string list haskell types integer


    【解决方案1】:

    ages ++ [age1]ages ++ [age2] 是导致[Int] 的表达式。他们不会修改agesages 只是一个值。由于您根本没有使用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
    

    【讨论】:

    • 我将来会使用它,我正在尝试将两个孩子的年龄添加到名为ages的列表中
    • 感谢您更新答案。我明白你的意思。但我想的是实现这一点,以便用户可以输入任意数量的孩子。如果我这样做,那么我们会限制孩子的数量。我将使用循环更新代码以显示我的意思。
    • 如果您静态地知道只有 2 个输入,那么最好使用一对而不是列表。
    • @RainMan:如果您的问题适合 Stack Overflow,您可以提出问题并在必要时从这里向我指出!通过这种方式,您更有可能获得及时、完整的答案。 =) 如果没有,我想你可以给我发一封电子邮件——见github.com/minitech
    【解决方案2】:

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

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

    这个递归函数在它的参数中记录年龄。定义的第一行检查读取的最新年龄是否为0。如果是这样,它将返回除0 之外的所有内容。如果一个列表至少有一个元素并且它的头部是0,那么它会匹配模式(0:otherAges)。如果匹配,则尾部绑定到otherAges。否则,它会转到下一个模式(这里是下一行)。

    我留下了递归的情况来填写,但我可以提供更多帮助。您需要在一个时代中读取并使用带有新时代的列表来称呼自己的东西。部分阅读内容看起来与您问题中的代码中的内容大致相同。

    【讨论】:

      猜你喜欢
      • 2014-02-07
      • 1970-01-01
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      • 2014-09-18
      相关资源
      最近更新 更多