Haskell 如何在不使用列表的情况下编写reverseT?

Haskell 如何在不使用列表的情况下编写reverseT?,haskell,reverse,foldable,representable,Haskell,Reverse,Foldable,Representable,我需要一个reverseT的替代方案,它不使用toList。 显然,这段代码是不正确的,但它表明了我所追求的理念: reverseF :: (Foldable f, Representable f, Num (Rep f)) => f a -> f a reverseF f = tabulate $ \ix -> index f $ last - ix where last = length f - 1 -- Incorrect; length -> ?

我需要一个
reverseT
的替代方案,它不使用
toList
。 显然,这段代码是不正确的,但它表明了我所追求的理念:

reverseF
  :: (Foldable f, Representable f, Num (Rep f))
  => f a -> f a
reverseF f = tabulate $ \ix -> index f $ last - ix
  where last = length f - 1  -- Incorrect; length -> ?

有人知道我可以用什么替换
length
,以便在构建
f
时获得
tablete
提供的最后一个索引元素吗?

您可以假设并使用
有界(Rep f)
枚举(Rep f)
,即用
toEnum
Rep f
转换为
Int
,通过使用
minBound
maxBound
Rep f
上的
Int
算法更改索引(或假设
fromnum minBound==0
),最后,从
Int
返回到
Rep f
,使用
fromnum
Representable
通常不支持
反向
,因为无限固定形状结构是可表示的,但不可逆的,例如。G溪流:

{-# language DeriveFunctor, TypeFamilies #-}

import Data.Distributive
import Data.Functor.Rep

data Stream a = Cons {hd :: a, tl :: Stream a} deriving Functor

instance Distributive Stream where
  distribute fa = Cons (hd <$> fa) (distribute (tl <$> fa))

data Nat = Z | S Nat

instance Representable Stream where
  type Rep Stream = Nat
  tabulate f      = Cons (f Z) (tabulate (f . S))
  index as Z      = hd as
  index as (S n)  = index (tl as) n

使用,您可以对任何
可遍历的t
进行
覆盖(部分遍历)反向::可遍历的t=>t~>t
Traversable
约束还确保我们保持了
t
的形状。额外的挑战:使用不同的函子不使用部分函数。谢谢!您的解决方案看起来像是作为中间状态通过列表。不是这样吗?@dbanas是的。使用
可遍历的
解决方案,您不会做得更好。@dfeuer解决方案带来额外的挑战。很好!我怀疑你真的需要这种温和的恶作剧(插件或
不安全的
)来提高效率,但以某种方式避免它们会更酷。
import Control.Monad.State.Strict

reverseT :: Traversable t => t a -> t a
reverseT ta =
  evalState (traverse (\_ -> gets head <* modify tail) ta)
            (foldl (flip (:)) [] ta)