我正在实现一个函数来执行N次单值计算。我写了以下代码。
performN :: Monad m => Int -> m t -> m [t]
performN 0 m = return []
performN n m =
do x1<- m
x2<- if n == 1 then return [] else (m:performN (n-2) m)
return (x1:x2)
我收到以下错误。
:264:44:错误:
•无法将类型'm'与'[]'匹配 'm'是一个刚性类型变量,由 类型签名:
performN :: forall(m :: * - &gt; *)t。 Monad m =&gt; Int - &gt; m t - &gt; m [t]
at:260:13
预期类型:[m t]
实际类型:m [t]
•在'(:)'的第二个参数中,即'performN(n - 2)m'
在表达式中:(m:performN(n-2)m)
在'do'区块中: x2&lt; - 如果n == 1则返回[] else(m:performN(n - 2)m)
•相关约束包括
m :: m t(约束:262:12)
performN :: Int - &gt; m t - &gt; m [t](约束于:261:1)
我似乎无法弄清楚我做错了什么以及如何解决它。
答案 0 :(得分:8)
你做了零次正确的事。
performN :: Monad m => Int -> m t -> m [t]
performN 0 m = return []
你有第一部分做了n次正确的事情:做一次。
performN n m = do
x1 <- m
但是你要做的就是再做n次1次。没有奇怪的if
东西。
performN n m = do
x1 <- m
x2 <- performN (n - 1) m
return (x1 : x2)
答案 1 :(得分:4)
太多的东西。 n == 1
? n-2
?为什么?简单!
performN :: Monad m => Int -> m t -> m [t]
performN 0 _ = return []
performN n m =
do x <- m
xs <- performN (n-1) m
return $ x:xs
答案 2 :(得分:0)
如果你需要使用这个功能,而不是需要实践它,你应该使用Control.Monad.replicateM而不是自己重新实现它。