Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
初学者haskell代码在main中使用do构造获取类型错误_Haskell - Fatal编程技术网

初学者haskell代码在main中使用do构造获取类型错误

初学者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

我只是在学习一些浅显的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
      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及其工作原理的一点事实。压痕只是我草率的工作,我不敢相信我错过了。