将monad限制为类型类

时间:2008-12-18 22:28:16

标签: haskell types monads typeclass

在Haskell中,有没有办法限制monad M a以便a满足类型类约束?

我正在将probabilistic modeling exampleF#翻译为Haskell。但是,在Haskell中,我省略了support,因为它会将data Distribution a更改为data (Ord a) => Distribution 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'

确实,always / return的类型为:(Ord a) => a -> Distribution a。有没有办法让我有一个monad Distribution,但强制约束(Ord a)在这个monad上?我试过了:

instance Monad Distribution where
    (>>=) = bind
    return :: (Ord a) => a -> Distribution a = always

但我收到错误:

...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.

所以有一种方法可以使用monad M a,但使用a等约束限制Ord a

感谢。

3 个答案:

答案 0 :(得分:13)

看来我在Haskell遇到了一个众所周知的问题。 found many workarounds googling for "restricted monads" This solutions。 {{3}}似乎是最不具破坏性的。不过,就我的目的而言,这似乎有些过分。我认为我将保持Distribution monad general,并通过受限制的函数简化支持,如Revolucent所示。

答案 1 :(得分:10)

我对此的理解是你根本不能,因为monad意在对所有类型进行推广,而不是某些类型的限制子集,例如(Ord a)

您可以简单地限制使用该monadic类型的函数,而不是限制monadic类型M a,例如,

foo :: Ord a => Int -> M a

实际上,最好将类型保持为尽可能通用,并仅使用类型类来限制函数。

答案 2 :(得分:3)

结帐Martin Erwig's library, PFP

  

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