haskell - 如果 a 有 Monoid,是否可以为 Identity a 编写 Alternative 实例?
问题描述
我想为新类型写一个Alternative
实例Identity
。骨架并不难:
instance Alternative Identity where
empty = _
(<|>) = _
但是,所有类型都无法实现。如果我有一个 Monoid 实例,那将很容易a
:
instance Alternative Identity where
empty = Identity mempty
(Identity a) <|> (Identity a') = Identity (a <> a')
有没有办法告诉编译器我只想在Alternative
内部类型具有 Monoid 实例时才定义实例?由于a
没有在任何地方提及,我不能只使用约束Monoid a =>
。
解决方案
Alternative
必须提供所有类型,empty
没有限制。否则,不履行合同。a
Alternative
也就是说,如果我们有一个实例Alternative f
,我们必须有
empty :: forall a . f a
没有任何进一步的限制。
因此,Identity
不是一个Alternative
。
这是一个已知问题,在许多类似的类型类中都可以找到。例如,许多人会喜欢一个Functor Set
实例,但这需要
fmap :: (a -> b) -> Set a -> Set b
对于所有类型a
和b
,而上面的功能只能在Ord
类型上实现。由于我们不能添加约束,所以我们没有得到函子。
不过,可以尝试使用一种更通用的类型类来解释额外的约束。也许像
class CFunctor c f where
fmap :: (c a, c b) => (a->b) -> f a -> f b
class CFunctor c f => CApplicative c f where
empty :: c a => f a
(<*>) :: (c a, c b, c (a->b)) => f (a->b) -> f a -> f b
但这些不是图书馆中的“标准”。(我猜在hackage上应该有类似于上面的约束类变体的东西。)
推荐阅读
- ansible - Ansible 主机文件解析未按预期工作
- jpa - JPA 加入 childEntity.childForeignEntity
- mysql - 当我的mysql存储过程没有找到任何结果时,我想抛出一个异常
- excel - 将 MIN/MAX 应用到数组的 LET 函数的奇怪行为
- reactjs - 布尔值不保存到状态。使用 react-redux
- flutter - 到达结果底部时如何将更多项目加载到列表中
- c# - C#如何停止RichTextBox重绘?
- javascript - 为什么这段代码会创建填充相同重复值的数组?
- python - bot 执行下一个命令而不等待消息
- excel - 查找搜索重复值并返回备用列值