我正在努力了解这背后的动机MonadPlus.如果已经有类型Monad和Monoid?为什么有必要?
当然,实例Monoid是具体类型,而实例Monad需要单个类型参数.(有关有用的解释,请参阅Monoid与MonadPlus.)但是你不能重写任何类型约束
(MonadPlus m) => ...
Run Code Online (Sandbox Code Playgroud)
作为Monad和Monoid?的组合?
(Monad m, Monoid (m a)) => ...
Run Code Online (Sandbox Code Playgroud)
例如,guard从中获取功能Control.Monad.它的实施是:
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
Run Code Online (Sandbox Code Playgroud)
我只能使用Monad和实现它Monoid:
guard' :: (Monad m, Monoid (m ())) => Bool -> m ()
guard' True = return ()
guard' False = mempty
Run Code Online (Sandbox Code Playgroud)
有人可以澄清 …
我之前已经定义了一个函数,它接受一个Maybes 列表并将其转换Maybe为一个列表,如下所示:
floop :: [Maybe a] -> Maybe [a]
floop [] = Just []
floop (Nothing:_) = Nothing
floop (Just x:xs) = fmap (x:) $ floop xs
Run Code Online (Sandbox Code Playgroud)
现在我想重新定义它是一个较大的容器类,不只是名单的兼容,而且我发现,它需要实现的功能foldr,mappend,mempty,fmap,和pure; 所以我认为以下类型行是合适的:
floop :: (Foldable t, Functor t, Monoid t) => t (Maybe a) -> Maybe (t a)
Run Code Online (Sandbox Code Playgroud)
正如(我认为)它确保为给定容器实现这些功能,但是它会导致以下错误:
Expecting one more argument to ‘t’
The first argument of ‘Monoid’ should have kind ‘*’,
but ‘t’ has kind ‘* …Run Code Online (Sandbox Code Playgroud)