初学者haskell代码在main中使用do构造获取类型错误
我只是在学习一些浅显的haskell代码,但是我所遵循的教程没有提到我在尝试运行任何do和I/O类型的代码时继续遇到的这个错误。GHCI似乎认为这是某种类型的错误。这是我的密码:初学者haskell代码在main中使用do构造获取类型错误,haskell,Haskell,我只是在学习一些浅显的haskell代码,但是我所遵循的教程没有提到我在尝试运行任何do和I/O类型的代码时继续遇到的这个错误。GHCI似乎认为这是某种类型的错误。这是我的密码: main = do putStrLn "This program can find all odd numbers between 1 and a desired number. Please enter a number." user <- getLine if (read user) < 1
main = do
putStrLn "This program can find all odd numbers between 1 and a desired number. Please enter a number."
user <- getLine
if (read user) < 1
then
do putStrLn "Improper input specified. 10 will be chosen as default."
putStrLn show oddsort 10 [] ++ "Is the list of odd numbers from 1 to 10."
else
do putStrLn show (oddsort (read user) [])
oddsort x xs
|x == 1 = 1:xs
|x `mod` 2 == 0 = oddsort (x-1) xs
|otherwise = oddsort (x - 2) (x:xs)
main=do
putStrLn“此程序可以找到1和所需数字之间的所有奇数。请输入一个数字。”
用户您的代码中有两个错误:
oddsort :: Int -> [Int] -> [Int]
oddsort x xs
|x == 1 = x : xs
|x `mod` 2 == 0 = oddsort (x - 1) (x:xs)
|otherwise = oddsort (x - 2) (x:xs)
main = do
putStrLn "This program can find all odd numbers between 1 and a desired number. Please enter a number."
user <- getLine
if (read user :: Int) < 1
then putStrLn $ "Improper input specified. 10 will be chosen as default. \n" ++ ((show $ oddsort 10 []) ++ " Is the list of odd numbers from 1 to 10.")
else putStrLn $ show $ (oddsort (read user :: Int) [])
缩进。始终确保属于do
块的所有行缩进到同一级别
main = do
⋮putStrLn "This program..."
⋮user <- getLine
⋮if (read user) < 1
⋮ then
⋮ do⋮putStrLn "Improper..."
⋮ ⋮█putStrLn ...
⋮ else
⋮ do putStrLn ...
虽然putStrLn
可能看起来像是一个“行开头的命令”,总是这样解析,但事实并非如此——它只是一个普通函数。因此,putStrLn show oddsort 10[]+“Bla”
被解析为
(putStrLn show oddsort 10 []) ++ "Bla"
i、 e.putStrLn
应用于参数show
、oddsort
、10
和[]
。显然,它不知道如何处理所有这些,也就是说,这是一个巨大的类型错误!你真正想要的是
putStrLn (show (oddsort 10 []) ++ "Bla")
也可以使用“parenthisation运算符”$
编写:
putStrLn $ show (oddsort 10 []) ++ "Bla"
我将关注这些方面
do putStrLn "Improper input specified. 10 will be chosen as default."
putStrLn show oddsort 10 [] ++ "Is the list of odd numbers from 1 to 10."
问题:
缩进错误:块条目应完全从同一列开始
第二行解析为(putStrLn show oddsort 10[])+(“是从1到10的奇数列表”)
这是错误的,因为您不能+
像putStrLn show oddsort 10[]这样的非列表。你需要括号
putStrLn show oddsort 10[]
调用函数putStrLn
,其中包含4个参数:show
、oddsort
、10
和[]
。这不是你想要的,所以你需要更多的括号
可能还有更多的问题,但这些是最明显的问题
一般建议:向所有顶级绑定添加类型签名,如oddsort
。这将有助于GHC生成更好的类型错误消息。
此外,使用-Wall
打开警告也有助于检测某些问题。以下是代码的工作版本:
oddsort :: Int -> [Int] -> [Int]
oddsort x xs
|x == 1 = x : xs
|x `mod` 2 == 0 = oddsort (x - 1) (x:xs)
|otherwise = oddsort (x - 2) (x:xs)
main = do
putStrLn "This program can find all odd numbers between 1 and a desired number. Please enter a number."
user <- getLine
if (read user :: Int) < 1
then putStrLn $ "Improper input specified. 10 will be chosen as default. \n" ++ ((show $ oddsort 10 []) ++ " Is the list of odd numbers from 1 to 10.")
else putStrLn $ show $ (oddsort (read user :: Int) [])
oddsort::Int->[Int]->[Int]
oddsort x xs
|x==1=x:xs
|x`mod`2==0=oddsort(x-1)(x:xs)
|否则=oddsort(x-2)(x:xs)
main=do
putStrLn“此程序可以找到1和所需数字之间的所有奇数。请输入一个数字。”
用户发布完整的错误消息对于此类问题非常重要。否则,人们不得不猜测,或者花费更多的精力将代码复制到文件中,然后看到错误。这通常会导致更少、更不精确的答案。虽然公平地说,在这种情况下,错误消息确实不会帮助更快地找到错误。但是将来,即使错误消息很笨重,也一定要添加错误消息。如果您使用显式分隔符do{…;…}
,您将永远不必担心代码被意外缩进破坏。非常感谢!这回答了我需要知道的一切,我不敢相信我的教程遗漏了关于putStrLn及其工作原理的一点事实。压痕只是我草率的工作,我不敢相信我错过了。