在 haskell 中输入错误
Type errors in haskell
在 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
是一个包含 child 两人年龄的列表。将来会用到。还创建了循环
ages ++ [age1]
和 ages ++ [age2]
是导致 [Int]
的表达式。他们不修改 ages
; ages
只是一个值。因为你根本没有使用 ages
,一个非常简单的修复就是把所有三行都去掉:
let ages = []
ages ++ [age1]
ages ++ [age2]
ages
可以从 age1
和 age2
构建,如果你打算将它用作 [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
在Haskell中,变量是不可变的。您可能正在寻找更像这样的东西:
inputAges :: [Int] -> IO [Int]
inputAges (0:otherAges) = return otherAges
inputAges ages = _
此递归函数在其参数中跟踪年龄。定义的第一行检查读取的最新年龄是否为 0
。如果是这样,它会返回除 0
之外的所有内容。如果一个列表至少有一个元素并且它的头部是 0
,那么它将匹配模式 (0:otherAges)
。如果匹配,则尾部绑定到 otherAges
。否则,它将转到下一个模式(此处为下一行)。
我将递归案例留待填写,但我可以在这方面提供更多帮助。你需要一些在一个时代读取并用一个带有新时代前缀的列表来调用自己的东西。部分阅读内容与您问题中的代码看起来非常相似。
在 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
是一个包含 child 两人年龄的列表。将来会用到。还创建了循环
ages ++ [age1]
和 ages ++ [age2]
是导致 [Int]
的表达式。他们不修改 ages
; ages
只是一个值。因为你根本没有使用 ages
,一个非常简单的修复就是把所有三行都去掉:
let ages = []
ages ++ [age1]
ages ++ [age2]
ages
可以从 age1
和 age2
构建,如果你打算将它用作 [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
在Haskell中,变量是不可变的。您可能正在寻找更像这样的东西:
inputAges :: [Int] -> IO [Int]
inputAges (0:otherAges) = return otherAges
inputAges ages = _
此递归函数在其参数中跟踪年龄。定义的第一行检查读取的最新年龄是否为 0
。如果是这样,它会返回除 0
之外的所有内容。如果一个列表至少有一个元素并且它的头部是 0
,那么它将匹配模式 (0:otherAges)
。如果匹配,则尾部绑定到 otherAges
。否则,它将转到下一个模式(此处为下一行)。
我将递归案例留待填写,但我可以在这方面提供更多帮助。你需要一些在一个时代读取并用一个带有新时代前缀的列表来调用自己的东西。部分阅读内容与您问题中的代码看起来非常相似。