In Haskell, is there a way to restrict a monad M a
so that a
satisfy a type class constraint?
在Haskell中,有没有办法限制monad M a以满足类型类约束?
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:
我正在将概率建模示例从F#转换为Haskell。但是,在Haskell中,我省略了支持,因为它会将数据分配a更改为数据(Ord a)=>分布a。通过此更改,我收到以下错误:
...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:
实际上,always / return的类型是:(Ord a)=> a - >分布a。有没有办法让我可以拥有monad分布,但强制约束(Ord a)在这个monad上?我试过了:
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
?
那么有一种方法可以使用monad M a,但是使用Ord a等约束来限制a?
Thanks.
3 个解决方案
#1
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)
.
我对此的理解是你根本不可能,因为monad意在对所有类型进行推广,而不是某些类型的有限子集,如(Ord a)。
Instead of restricting the monadic type M a
, you can simply restrict functions which use that monadic type, e.g.,
您可以简单地限制使用该monadic类型的函数,而不是限制monadic类型M a,例如,
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.
#2
It appears that I ran into a well-known problem in Haskell. I found many workarounds by googling for "restricted monads". This solutions seems to be the least disruptive. Still, for my purposes, it seems overkill. I think I'll keep the Distribution
monad general, and simplify a support via a restricted function, as suggested by Revolucent.
看来我在Haskell遇到了一个众所周知的问题。我通过Google搜索“受限制的monad”找到了许多变通方法。这种解决方案似乎是破坏性最小的。不过,就我的目的而言,这似乎有些过分。我认为我将保持发布monad的一般性,并通过受限制的功能简化支持,如Revolucent所建议的那样。
#3
Check out Martin Erwig's library, PFP:
查看Martin Erwig的图书馆,PFP:
The PFP library is a collection of modules for Haskell that facilitates probabilistic functional programming, that is, programming with stochastic values. The probabilistic functional programming approach is based on a data type for representing distributions. A distribution represent the outcome of a probabilistic event as a collection of all possible values, tagged with their likelihood.
PFP库是Haskell模块的集合,它促进了概率函数编程,即使用随机值编程。概率函数编程方法基于用于表示分布的数据类型。分布表示概率事件的结果,作为所有可能值的集合,标记其可能性。
#1
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)
.
我对此的理解是你根本不可能,因为monad意在对所有类型进行推广,而不是某些类型的有限子集,如(Ord a)。
Instead of restricting the monadic type M a
, you can simply restrict functions which use that monadic type, e.g.,
您可以简单地限制使用该monadic类型的函数,而不是限制monadic类型M a,例如,
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.
#2
It appears that I ran into a well-known problem in Haskell. I found many workarounds by googling for "restricted monads". This solutions seems to be the least disruptive. Still, for my purposes, it seems overkill. I think I'll keep the Distribution
monad general, and simplify a support via a restricted function, as suggested by Revolucent.
看来我在Haskell遇到了一个众所周知的问题。我通过Google搜索“受限制的monad”找到了许多变通方法。这种解决方案似乎是破坏性最小的。不过,就我的目的而言,这似乎有些过分。我认为我将保持发布monad的一般性,并通过受限制的功能简化支持,如Revolucent所建议的那样。
#3
Check out Martin Erwig's library, PFP:
查看Martin Erwig的图书馆,PFP:
The PFP library is a collection of modules for Haskell that facilitates probabilistic functional programming, that is, programming with stochastic values. The probabilistic functional programming approach is based on a data type for representing distributions. A distribution represent the outcome of a probabilistic event as a collection of all possible values, tagged with their likelihood.
PFP库是Haskell模块的集合,它促进了概率函数编程,即使用随机值编程。概率函数编程方法基于用于表示分布的数据类型。分布表示概率事件的结果,作为所有可能值的集合,标记其可能性。