haskell - 将类型参数限制为 Monoid

标签 haskell types type-kinds

我之前定义了一个函数,它接受一个列表 Maybe s 并将其变成 Maybe一个列表,像这样:

floop :: [Maybe a] -> Maybe [a]
floop [] = Just []
floop (Nothing:_) = Nothing
floop (Just x:xs) = fmap (x:) $ floop xs

现在我想重新定义它以兼容更大类的容器,而不仅仅是列表,我发现它需要实现功能foldr , mappend , mempty , fmap , 和 pure ;所以我认为以下类型行是合适的:
floop :: (Foldable t, Functor t, Monoid t) => t (Maybe a) -> Maybe (t a)

因为(我认为)它确保为给定的容器实现了这些功能,但是它会导致以下错误:
Expecting one more argument to ‘t’
The first argument of ‘Monoid’ should have kind ‘*’,
  but ‘t’ has kind ‘* -> *’
In the type signature for ‘floop'’:
  floop' :: (Foldable t, Functor t, Monoid t) =>
            t (Maybe a) -> Maybe (t a)

查了一下,发现Monoid的种类与Functor的种类不同和 Foldable ,但我不明白为什么会这样,也不明白如何纠正错误。

对于那些感兴趣的人,这是当前的实现:
floop :: (Foldable t, Functor t, Monoid t) => t (Maybe a) -> Maybe (t a)
floop xs = let
                f :: (Foldable t, Functor t, Monoid t) => Maybe a -> Maybe (t a) -> Maybe (t a)
                f Nothing _ = Nothing
                f (Just x) ys = fmap (mappend $ pure x) ys
            in
                foldr f (Just mempty) xs

注意:我已经知道这已经作为一个内置函数存在 ( sequence ),但我打算将它作为一个学习练习来实现。

最佳答案

幺半群应用由 Alternative 描述类,使用 (<|>)empty而不是 mappendmempty :

floop :: (Foldable t, Alternative t) => t (Maybe a) -> Maybe (t a)
floop xs = let
                f :: (Foldable t, Alternative t) => Maybe a -> Maybe (t a) -> Maybe (t a)
                f Nothing _ = Nothing
                f (Just x) ys = fmap ((<|>) $ pure x) ys
            in
                foldr f (Just empty) xs 

关于haskell - 将类型参数限制为 Monoid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41981432/

相关文章:

haskell - 可存储向量和未装箱向量之间的差异

haskell - 在 Haskell 中实现内存功能

javascript - 当我们更改类型值时触发替换

arrays - 无法转换数组中的返回表达式

haskell - Haskell 中的 "*"到底是什么?

xml - 在 Haskell 中,如何从 XML 文档中提取字符串?

list - 计算两个字符串之间的差异

python - python中的类类型

scala - 未找到 Kind 编译器插件 λ