我无法写一个函数类型数组
Int -> IO [Int]
或Int -> [IO Int]
哈斯克尔IO和递归
我有下面的代码不工作:
createEIList :: Int -> IO [Int]
createEIList len = do
cur <- createEI
(return cur):(createEIList (len-1))
哪里createEI是createEI :: IO Int
做这种事情的最佳方法是什么?
我无法写一个函数类型数组
Int -> IO [Int]
或Int -> [IO Int]
哈斯克尔IO和递归
我有下面的代码不工作:
createEIList :: Int -> IO [Int]
createEIList len = do
cur <- createEI
(return cur):(createEIList (len-1))
哪里createEI是createEI :: IO Int
做这种事情的最佳方法是什么?
为了保持它接近你原本
createEIList :: Int -> IO [Int]
createEIList len = do
cur <- createEI
rest <- createEIList (len-1)
return (cur:rest)
这样,你不要试图追加IO Int
到您的列表,而是返回整个列表提升您[Int]
到IO [Int]
你也可能需要一个基本情况
createEIList 0 = return []
createEIList n = ...
以便递归实际终止。
另外值得注意的是,您可以用组合子
replicateM :: Int -> IO a -> IO [a] -- Restricted for clarity
我要把它留给你找出如何使用这个删除显式递归。
但是':'不会有'Int'类型的左参数和'IO Int'类型的右参数吗? – functorial
@ user2529202修正了,你把它明确的绑定到一个名字上去删除它的monadic wrapper – jozefg
'<-'删除了IO,然后你可以用新元素 – jozefg
最后一行应该是createEIList (len-1) >>= \a -> return (cur:a)
我认为这将是更好地坚持到'do'记法,而不是拉姆达,因为我们已经在那。 –
我想确保我可以用一行来回答,而不必重写整个事情或冒险造成混淆。 – randomusername
这不会终止。 –
createEIList :: Int -> IO Int
createEIList len = createEI >>= return . replicate len
或
createEIList :: Int -> IO Int
createEIList len = createEI >>= replicateM len . return
更好的解决方案:
createEIList :: Int -> IO Int
createEIList len = replicateM len createEI
tersest:
createEIList :: Int -> IO Int
createEIList = flip replicateM createEI
应用性:
import Control.Applicative
createEIList len = replicate <$> pure len <*> createEI
createEIList' len = liftA2 replicate (pure len) createEI
replicateM :: Monad的M =>内部 - >马 - > M [A],研究这种类型 –