list - Codetity与 `DList`和 `[]`之间的关系

标签 list haskell category-theory

我最近一直在尝试Codensity,它应该将DList[]关联起来。无论如何,我从来没有找到说明这种关系的代码。经过一些实验,我得出了以下结论:

{-# LANGUAGE RankNTypes #-}
module Codensity where

newtype Codensity f a = Codensity
  { runCodensity :: forall b. (a -> f b) -> f b }

type DList a = Codensity [] [a]

nil :: DList a
nil = Codensity ($ [])

infixr 5 `cons`
cons :: a -> DList a -> DList a
cons x (Codensity xs) = Codensity ($ (xs (x:)))

append :: DList a -> DList a -> DList a
append (Codensity xs) ys = Codensity ($ (xs (++ toList ys)))

toList :: DList a -> [a]
toList xs = runCodensity xs id

fromList :: [a] -> DList a
fromList xs = Codensity (\k -> k xs)

但是,在我的示例中,DList的定义有点棘手。有没有另一种方式陈述这种关系?这甚至是正确的方法吗?

最佳答案

有一种观点可能是DList是一种重新排序monoid操作的方法,就像Codensity是一种重新排序monad操作的方法一样。
[]a上的免费monoid,所以让我们使用免费的作家monad来表示列表,即Free ((,) a):

module Codensity where

import Control.Monad
import Control.Monad.Free
import Control.Monad.Codensity
import Control.Monad.Trans (lift)

type DList a = Free ((,) a) ()

现在我们可以定义标准列表操作:
nil :: DList a
nil = return ()

singleton :: a -> DList a
singleton x = liftF (x, ())

append :: DList a -> DList a -> DList a
append = (>>)

infixr 5 `snoc`
snoc :: DList a -> a -> DList a
snoc xs x = xs >> singleton x

exec :: Free ((,) a) () -> [a]
exec (Free (x, xs)) = x : exec xs
exec (Pure _) = []

fromList :: [a] -> DList a
fromList = mapM_ singleton

toList :: DList a -> [a]
toList = exec

对于snoc,此表示形式与list具有相同的缺点。我们可以验证
last . toList . foldl snoc nil $ [1..10000]

需要大量(二次)时间。但是,就像每个免费的monad一样,可以使用Codensity对其进行改进。我们只是将定义替换为
type DList a = Codensity (Free ((,) a)) ()

toList
toList = exec . lowerCodensity

现在,相同的表达式将立即执行,因为Codensity对操作进行了重新排序,就像原始差异列表一样。

关于list - Codetity与 `DList`和 `[]`之间的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32191851/

相关文章:

haskell - 授予可遍历的 F 代数,是否可能对应用代数进行变形?

mysql - 项目列表的数据库结构(非常不同)

C++ STL 列表崩溃,数字超过 1 000 000 000

haskell - 柯里化(Currying)减法

haskell - 为什么我不能在 ghci 中定义新类型?

haskell - 如何在状态 monad 的字段上进行模式匹配?

haskell - 是否可以为 Arrows 而不是 ArrowApply 写下 join?

scala - Hom Functor 的逆变和Scala 的Function1 之间有什么联系吗?

C# List<string> 到带分隔符的字符串

Python删除列表字典中的重复项