将 monad 限制为类型类 [英] Restricting a monad to a type class
问题描述
在 Haskell 中,有没有办法限制 monad M a
以便 a
满足类型类约束?
我正在翻译 概率建模示例来自support
因为它会将 data Distribution a
更改为 data (Ord a) =>分发一个
.通过此更改,我收到以下错误:
...probabilisticModeling.hs:42:13:无法从上下文中推导出 (Ord a) ()源于使用总是"在 ...probabilisticModeling.hs:42:13-18可能的修复:将 (Ord a) 添加到 `return' 的类型签名的上下文中在表达中:总是在`return'的定义中:return = always在`Monad Distribution'的实例声明中
确实,always
/return
的类型是:(Ord a) =>->分发一个
.有没有办法让我拥有一个 monad Distribution
,但是在这个 monad 上强制约束 (Ord a)
?我试过了:
instance Monad Distribution where(>>=) = 绑定返回 :: (Ord a) =>->分布 a = 总是
但我收到错误:
...probabilisticModeling2.hs:48:4:实例声明中不允许使用模式绑定(简单变量除外)返回 :: (Ord a) =>->分布 a = 总是失败,加载的模块:无.
那么有没有办法让一个monad M a
,但是用Ord a
这样的约束来限制a
?>
谢谢.
我的理解是你根本不能,因为 monad 旨在泛化所有类型,而不是一些受限的类型子集,例如 (Ord a)
.
您可以简单地限制使用该 monadic 类型的函数,而不是限制 monadic 类型 M a
,例如,
foo :: Ord a => Int -> M a
实际上,最好保持类型尽可能通用,使用类型类仅用于限制功能.
等
In Haskell, is there a way to restrict a monad M a
so that a
satisfy a type class constraint?
I am translating the probabilistic modeling example from F# to Haskell. However, in Haskell, I omitted support
because it would change data Distribution a
to data (Ord a) => Distribution a
. With this change, I get the following error:
...probabilisticModeling.hs:42:13:
Could not deduce (Ord a) from the context ()
arising from a use of `always'
at ...probabilisticModeling.hs:42:13-18
Possible fix:
add (Ord a) to the context of the type signature for `return'
In the expression: always
In the definition of `return': return = always
In the instance declaration for `Monad Distribution'
Indeed, the type of always
/return
is: (Ord a) => a -> Distribution a
. Is there a way I can have a monad Distribution
, but force the constraint (Ord a)
on this monad? I tried:
instance Monad Distribution where
(>>=) = bind
return :: (Ord a) => a -> Distribution a = always
But I get the error:
...probabilisticModeling2.hs:48:4:
Pattern bindings (except simple variables) not allowed in instance declarations
return :: (Ord a) => a -> Distribution a = always
Failed, modules loaded: none.
So it there a way to have a monad M a
, but restrict the a
with a constraint such as Ord a
?
Thanks.
My understanding of this is that you simply cannot, because a monad is meant to be generalized over all types, not some restricted subset of types such as (Ord a)
.
Instead of restricting the monadic type M a
, you can simply restrict functions which use that monadic type, e.g.,
foo :: Ord a => Int -> M a
In fact, it is preferable to keep types as general as possible and use type classes only to restrict functions.
etc.
这篇关于将 monad 限制为类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!