将monad限制为类型类

时间:2021-09-03 17:04:30

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模块的集合,它促进了概率函数编程,即使用随机值编程。概率函数编程方法基于用于表示分布的数据类型。分布表示概率事件的结果,作为所有可能值的集合,标记其可能性。