如何实现索引核心风格索引连续单元 [英] How to implement index-core style indexed continuation monad

查看:147
本文介绍了如何实现索引核心风格索引连续单元的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我一直在研究(并试图理解)索​​引monad。我想我已经开始讨论一种索引monad的风格了,如下所述:无穷的邻里:超越Monads



但是,我在 index-core ,其中有一些部分看起来与这个索引monad绑定了两个索引,例如一个类似的绑定操作符> = !虽然它明显对索引有类似的更改,但我不太明白如何使用这些索引,例如,像在其他样式中一样控制连续monad中的返回类型。我会对这种索引monad感兴趣,主要是因为它对于monad变换器似乎工作得更好 - 实际上我没有看到在其他样式中定义的索引monad变换器(索引monad),只有一个索引变换器

我想知道是否有人可以请提供一个实现这种延续monad风格的两个结果类型continuation monad的示例,或者指向其他示例使用这个模块来定义其他使用两个索引的索引monad(例如,状态monad的形式可能会改变状态的类型)。我一直在寻找这样一个例子,没有太多的运气,而且我还没有成功地自己实现它。我有一种感觉,它应该是显而易见的,但我有一些在不同的构造函数绑定。

解决方案

m index-core 包的作者,答案是可以的。这是解决方案:

  { - #LANGUAGE TypeOperators,RankNTypes# - } 

import Control.Category .index
import Control.IMonad
import Data.Functor.Identity
$ b $ newtype ICont fai = ICont {runICont ::(a: - > f) - > fi}

请注意,我使用 f r r s将成为索引。



执行 IFunctor IMonad 与普通monad的实现相同(就像博客文章的版本一样):

 实例IFunctor(ICont f)其中
fmapI fm = bindI(returnI。f)m

实例IMonad(ICont f)其中
returnI = ICont $ \k - > k a
bindI f m = ICont $ \k - > runICont m $ \a - > runICont(fa)k

窍门是认识到它减少到您在博客中看到的版本当 f =身份

 (a  - > r2) - > r1 
〜(a - > Identity r2) - >身份r1
〜((a:= r2)r2 - >身份r2) - >身份r1
〜((a:= r2): - >身份) - >身份r1
〜ICont身份(a:= r2)r1
〜R ICont Identity r1 r2 a

唯一的区别是额外的 R 身份噪音,如果您选择匹配博客文章的版本:

  type ICont'r1 r2 a = ICont Identity(a:= r2)r1 

下面是使用 ICont

   -  example〜(String  - > Int) - > Char 
- example〜((String:= Int)Int - > Identity Int) - > Identity Char
example :: ICont'Char Int String
example = ICont $ \k - >身份
case runIdentity(k(VHello))
0 - > 'A'
_ - > 'B'

index-core 库受到Conor McBride的论文启发: Kleisli愤怒的财富箭头。请注意,Conor的方法需要比博客文章更为详细,但它提供了博客文章中没有的功能,主要是为了在索引中存储更强大的信息以提供更大的灵活性。 p>

这对您来说意味着如果您不需要这些额外功能,那么您应该使用您在博客文章中看到的功能。然而,我强烈建议你阅读Conor的论文,不管你选择什么,因为它是一篇非常出色的论文,并且显示了Haskell的类型系统的强大。



我没有不会为<$​​ c $ c> index-core 实现任何索引monad,主要是因为我编写了该库来为我写的另一个库搔痒。如果您想查看使用 index-core 的具体代码,只需查看 2.2.0 的 pipes 其中我使用 index-core 来实现索引空闲monad变换器。然而,我不再使用这种类型,尽管我仍然维护 index-core 包。



如果你有任何其他问题,随时问!


I have been looking at (and trying to understand) indexed monads recently. I think I have got my head around one style of indexed monad, as described here: A Neighbourhood of Infinity: Beyond Monads.

However, I have found a different style of indexed monad in index-core, which has some parts that seem to correspond to this indexed monad bind with two indexes, for example a similar bind operator !>=. While it clearly has similar changes to the indexes, I can't quite understand how to use these indexes, for example, to control the return types in a continuation monad as with the other style. I would be interested in this style of indexed monad, primarily because it seems to work a lot better for monad transformers - in fact I have not seen an indexed monad transformer (of indexed monads) defined in the other style, only an indexed transformer of regular monads.

I am wondering if anyone could please provide an example of the two result type continuation monad implemented as this style of continuation monad, or point me to other examples of the use of this module to define other indexed monads that make use of two indexes (for instance, the form of the state monad where the type of the state may change). I have been searching for such an example, without much luck, and I haven't managed to successfully implement it myself. I have a feeling it should be obvious, but I've got a bit tied up in the different constructors.

解决方案

I'm the author of the index-core package, and the answer is that you can. Here's the solution:

{-# LANGUAGE TypeOperators, RankNTypes #-}

import Control.Category.Index
import Control.IMonad
import Data.Functor.Identity

newtype ICont f a i = ICont { runICont :: (a :-> f) -> f i }

Note that I use f instead of r. The rs are going to be the indices.

The implementation of IFunctor and IMonad are identical to the implementation of the ordinary monad (just like the blog post's versions):

instance IFunctor (ICont f) where
    fmapI f m = bindI (returnI . f) m

instance IMonad (ICont f) where
    returnI a = ICont $ \k -> k a
    bindI f m = ICont $ \k -> runICont m $ \a -> runICont (f a) k

The trick is to realize that it reduces to the version you saw in the blog post when f = Identity

  (a -> r2) -> r1
~ (a -> Identity r2) -> Identity r1
~ ((a := r2) r2 -> Identity r2) -> Identity r1
~ ((a := r2) :-> Identity) -> Identity r1
~ ICont Identity (a := r2) r1
~ R ICont Identity r1 r2 a

The only difference is the extra R and Identity noise, which you can abstract away if you choose to match the blog post's version:

type ICont' r1 r2 a = ICont Identity (a := r2) r1

Here's an example of a function written using ICont

-- example ~ (String -> Int) -> Char
-- example ~ ((String := Int) Int -> Identity Int) -> Identity Char
example :: ICont' Char Int String
example = ICont $ \k -> Identity $
    case runIdentity (k (V "Hello")) of
        0 -> 'A'
        _ -> 'B'

The index-core library was inspired by Conor McBride's paper: Kleisli Arrows of Outrageous Fortune. Note that Conor's approach requires greater verbosity than the one in the blog post, but it affords extra features that the one in the blog post does not, mainly in the ability to store more powerful information in the indices that offer even greater flexibility.

What that means for you is that if you do not need those extra features then you should probably use the one you saw in the blog post. However, I highly recommend that you read Conor's paper no matter what you choose, because it is a really excellent paper and shows how powerful Haskell's type system can be.

I didn't implement any of the indexed monads for index-core, mainly because I wrote that library to scratch an itch of mine for another library I wrote. If you want to see the concrete code that uses index-core, just check out version 2.2.0 of the pipes package where I used index-core to implement the indexed free monad transformer. However, I no longer use that type any longer, although I still maintain the index-core package.

If you have any other questions, feel free to ask!

这篇关于如何实现索引核心风格索引连续单元的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆