Haskell 如何在代码中使用循环而不出现任何错误?
这是一个程序,GHC从用户处获取一个数字n,然后它形成一个n个数字的列表,该列表再次由用户给出。这段代码显示了循环的一些分析错误。如何删除该错误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
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]