如何实现索引核心样式的索引延续monad

7 monads haskell

我最近一直在寻找(并试图理解)索​​引monad.我想我已经掌握了一种索引monad的风格,如下所述:Infinity的邻居:超越Monads.

但是,我在index-core中发现了一种不同风格的索引monad ,它有一些部分似乎与这个带有两个索引的索引monad绑定相对应,例如类似的绑定运算符!> =.虽然它显然对索引有类似的更改,但我不太明白如何使用这些索引,例如,控制继续monad中的返回类型与其他样式一样.我会对这种索引monad的样式感兴趣,主要是因为它似乎对monad变换器工作得更好 - 实际上我还没有看到在另一种风格中定义的索引monad变换器(索引monad),只有一个索引变换器常规的单子.

我想知道是否有人可以提供一个实现为此样式的continuation monad的两个结果类型continuation monad的示例,或者指向使用此模块来定义使用两个索引的其他索引monad的其他示例(对于例如,国家monad的形式,国家的类型可能会改变).我一直在寻找这样一个例子,没有太多运气,我自己也没有成功地实现它.我觉得它应该是显而易见的,但我在不同的构造函数中有点束缚.

Gab*_*lez 9

我是该index-core软件包的作者,答案是你可以.这是解决方案:

{-# 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 }
Run Code Online (Sandbox Code Playgroud)

请注意,我使用f而不是r.该rs的将是指数.

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

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
Run Code Online (Sandbox Code Playgroud)

诀窍是要意识到它减少到你在博客文章中看到的版本 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
Run Code Online (Sandbox Code Playgroud)

唯一的区别是额外RIdentity噪音,如果您选择匹配博客文章的版本,您可以抽象出来:

type ICont' r1 r2 a = ICont Identity (a := r2) r1
Run Code Online (Sandbox Code Playgroud)

这是一个使用函数编写的示例 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'
Run Code Online (Sandbox Code Playgroud)

index-core:库是由科纳·麦克布赖德的论文的启发抱得美人归财富的Kleisli箭头.请注意,Conor的方法需要比博客文章更详细,但它提供了博客文章中没有的额外功能,主要是能够在索引中存储更强大的信息,提供更大的灵活性.

对您来说意味着如果您不需要这些额外的功能,那么您应该使用您在博客文章中看到的功能.但是,我强烈建议您阅读Conor的论文,无论您选择什么,因为它是一篇非常优秀的论文,并展示了Haskell的类型系统有多强大.

我没有实现任何索引monad index-core,主要是因为我编写了这个库来为我写的另一个库划伤我的痒.如果你想看到使用的具体代码index-core,只需查看我用来实现索引的免费monad转换器2.2.0pipes包的版本index-core.但是,我不再使用那种类型了,尽管我仍然保留index-core包装.

如果您有任何其他问题,请随时提出!