更多 rmonad 库?

发布于 2024-12-03 18:29:20 字数 426 浏览 2 评论 0原文

我想用 RMonad 做一些基本的事情。有没有办法使用“as monad”功能来

  • 拥有身份 rmonad,以应用 monad 转换器?
  • 有诸如 StateT 变压器之类的常见东西吗?
  • 向现有的 monad 添加约束? (例如,如果有人想要一个具有附加约束的 StateT

不幸的是,我还没有掌握诸如数据族等使其工作的东西......否则我可能会很乐意编写代码我。

编辑

我从库源中将 StateT 一起破解,看看它是否有效...

[ http:// Pastebin.com/VT3uyEgr]

I want to do some rudimentary things with RMonad. Are there ways of using the "as monad" functionality to

  • have an identity rmonad, to apply monad transformers to?
  • have common things like StateT transformers?
  • add a constraint to an existing monad? (e.g. if one wanted a StateT with additional constraints)

unfortunately I haven't yet grasped things like data families, etc. that make it work ... otherwise I'd probably be happy to write the code myself.

edit

I hacked StateT together from library sources, will see if it works ...

[ http://pastebin.com/VT3uyEgr ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自此以后,行同陌路 2024-12-10 18:29:20

快速浏览后,您的 StateT 版本看起来是正确的。不幸的是,使用 RMonad 等。等人。 确实需要复制几乎所有内容;我开始使用 Suit 编写一些代码,但放弃了,因为它涉及太多重复(最终我并不真正需要它)。

编辑:

根据我对 Suitable 工作方式的记忆,它是这样的:

考虑 Functor 类:Set 可以不是它的实例,因为它需要额外的 Ord 约束。

一个简单的方法是这样的:

{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}

import qualified Data.Set as S

class MyFunctor c a | c -> a where
      myfmap :: (MyFunctor c b) => (a -> b) -> c a -> c b

instance (Ord a) => MyFunctor S.Set a where
      myfmap = S.map

但这会返回以下错误:

Error: test.hs:11:16: Could not deduce (Ord b) arising from a use of `S.map'
    from the context (Ord a)
      bound by the instance declaration at /tmp/test.hs:10:10-37
    or from (MyFunctor S.Set b)
      bound by the type signature for
                 myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
      at /tmp/test.hs:11:7-20
    Possible fix:
      add (Ord b) to the context of
        the type signature for
          myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
        or the instance declaration
    In the expression: S.map
    In an equation for `myfmap': myfmap = S.map
    In the instance declaration for `MyFunctor S.Set a'

这是为什么?这是因为约束没有在实例级别保留或找到,因此 GHC 没有意识到使用 myfmap 时,应该对 有一个 Ord 约束b.

Suitable 类型用于显式创建一个约束字典,它允许您指定这些类型的约束:(

import Data.Suitable
import qualified Data.Set as S

class MyFunctor c where
      myfmap :: (Suitable c a, Suitable c b) => (a -> b) -> c a -> c b

instance MyFunctor S.Set where
      myfmap f s = withConstraintsOf s
                   $ \ SetConstraints
                       -> withResConstraints $ \ SetConstraints -> S.map f s

其中 SetConstraints 已在 Data.Suitable 中定义code>)

这个实现是有效的,但它确实使类型签名更加复杂,并且方法实现更加复杂(请注意,我们需要引入 SetConstraints 两次:一次为一个为Set a,另一个为Set b)。请注意,对于没有任何约束的类型,不需要任何 Suitable 约束函数。

我已经开始尝试在 Typeclassopedia 中创建类的合适版本,但由于实例变得相当复杂而放弃了。

Your version of StateT looks correct after a quick glance. Unfortunately, using RMonad et. al. does require duplicating just about everything; I started doing writing some code using Suitable and gave up because it involved too much duplication (and in the end I didn't really need it).

Edit:

From my memory of how Suitable works, it's something like this:

Consider the Functor class: Set can't be an instance of it because it needs the extra Ord constraint.

A naive approach would be something like:

{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}

import qualified Data.Set as S

class MyFunctor c a | c -> a where
      myfmap :: (MyFunctor c b) => (a -> b) -> c a -> c b

instance (Ord a) => MyFunctor S.Set a where
      myfmap = S.map

But this then returns the following error:

Error: test.hs:11:16: Could not deduce (Ord b) arising from a use of `S.map'
    from the context (Ord a)
      bound by the instance declaration at /tmp/test.hs:10:10-37
    or from (MyFunctor S.Set b)
      bound by the type signature for
                 myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
      at /tmp/test.hs:11:7-20
    Possible fix:
      add (Ord b) to the context of
        the type signature for
          myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
        or the instance declaration
    In the expression: S.map
    In an equation for `myfmap': myfmap = S.map
    In the instance declaration for `MyFunctor S.Set a'

Why is this? It's because the constraint isn't kept or found at the instance level, so GHC doesn't realise that when using myfmap, there should be an Ord constraint on b.

The Suitable type is used to explicitly create a constraint dictionary which allows you to specify these kinds of constraints:

import Data.Suitable
import qualified Data.Set as S

class MyFunctor c where
      myfmap :: (Suitable c a, Suitable c b) => (a -> b) -> c a -> c b

instance MyFunctor S.Set where
      myfmap f s = withConstraintsOf s
                   $ \ SetConstraints
                       -> withResConstraints $ \ SetConstraints -> S.map f s

(where SetConstraints is already defined in Data.Suitable)

This implementation works, but it does make type signatures a bit more convoluted, and method implementations a bit hairier (note here that we need to bring in SetConstraints twice: once for the Set a, the other for the Set b). Note that for types without any constraints, none of the Suitable constraint functions are needed.

I had started to try and create Suitable versions of the classes in the Typeclassopedia but gave up because the instances were getting rather hairy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文