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 如何在代码中使用循环而不出现任何错误?_Haskell_Loops - Fatal编程技术网

Haskell 如何在代码中使用循环而不出现任何错误?

Haskell 如何在代码中使用循环而不出现任何错误?,haskell,loops,Haskell,Loops,这是一个程序,GHC从用户处获取一个数字n,然后它形成一个n个数字的列表,该列表再次由用户给出。这段代码显示了循环的一些分析错误。如何删除该错误 import System.IO main = do putStrLn "Please enter the number" number <- readLn :: IO Int putStrLn $ "The num is:" ++ show number loop number xs <- sequenc

这是一个程序,GHC从用户处获取一个数字n,然后它形成一个n个数字的列表,该列表再次由用户给出。这段代码显示了循环的一些分析错误。如何删除该错误

import System.IO

main = do 
   putStrLn "Please enter the number"
   number <- readLn :: IO Int
   putStrLn $ "The num is:" ++ show number
   loop number
   xs <- sequence [readLn :: IO Int]
   putStrLn xs

loop:: Int -> IO ()
loop n = if 0==n then return () else return loop (n-1)
import System.IO
main=do
putStrLn“请输入号码”

数字您的代码中有三个错误。在GHC中复制并启动它会显示以下消息:

temp.hs:9:13
    Couldn't match expected type `Char' with actual type `Int'
    Expected type: String
      Actual type: [Int]
    In the first argument of `putStrLn', namely `xs'
    In the expression: putStrLn xs
这一点很清楚
putStrLn
需要一个
String
,但是
xs
Int
s的列表。因此,只需使用
print xs
而不是
putstrn xs
就可以解决问题(
print=putstrn.show

接下来的两个问题实际上是相同的:

    temp.hs:13:38:
        No instance for (Monad ((->) t0))
          arising from a use of `return'
        Possible fix: add an instance declaration for (Monad ((->) t0))
        In the expression: return loop (n - 1)
        In the expression:
          if 0 == n then return () else return loop (n - 1)
        In an equation for `loop':
            loop n = if 0 == n then return () else return loop (n - 1)

temp.hs:13:45:
    Couldn't match expected type `IO ()'
                with actual type `Int -> IO ()'
    In the first argument of `return', namely `loop'
    In the expression: return loop (n - 1)
    In the expression:
      if 0 == n then return () else return loop (n - 1)
问题在于类型<代码>循环
的类型为
Int->IO()
。因此函数的第一个分支是正确的,因为您
return()
。但是,在else分支中,返回的是完全不同的内容,因为
return
不是该语言的某个内置语句,而是一个普通函数。因此
返回循环(n-1)
首先将
循环
函数提升到monad中,然后将其应用到
(n-1)

相反,您想要的是:

loop n = if n == 0 then return () else loop (n - 1)
还要注意的是,在Haskell中不需要
0==n
,因为没有办法意外地使用赋值而不是相等比较(它不会编译)


编辑:正如其他答案所指出的,
循环实际上并没有做任何事情-它只调用自己n-1次,然后返回()。

除了其他答案所说的:

您不需要编写循环函数

import System.IO

main = do 
   putStrLn "Please enter the number"
   number <- readLn :: IO Int
   putStrLn $ "The num is:" ++ show number
   xs <- sequence (replicate number (readLn :: IO Int))  -- pay attention to this line
   print xs
import System.IO
main=do
putStrLn“请输入号码”

数字若我正确理解了您的意图,您的意思是创建一个“循环”构造,该构造将执行一个操作n次,并生成一个结果列表。在你的代码中

loop number
xs <- sequence [readLn :: IO Int]
现在,您当然需要重写
循环
,以接受操作作为参数

loop :: Int -> IO a -> IO [a]
loop 0 action = return []  -- don't perform the action
loop n action = do
  x <- action              -- perform the action once
  xs <- loop (n-1) action  -- then perform it (n-1) times
  return (x:xs)            -- produce the resultant list

序列。复制n
replicateM n
:)@ehird这是真的,虽然
replicateM
不在前奏曲中,我觉得初学者在学习基于它的琐碎函数之前应该理解
sequence
。哈,我从来没有意识到
sequence
在前奏曲中,但
replicateM
不在前奏曲中。真奇怪。但是是的,在这种情况下打高尔夫球可能还为时过早。
loop :: Int -> IO a -> IO [a]
loop 0 action = return []  -- don't perform the action
loop n action = do
  x <- action              -- perform the action once
  xs <- loop (n-1) action  -- then perform it (n-1) times
  return (x:xs)            -- produce the resultant list
xs <- replicateM number readLn :: IO [Int]