use*_*391 7 haskell haskell-pipes
有时需要执行一些复杂的例程来检索或保存正在处理的数据.在这种情况下,人们想要分离数据生成和数据处理逻辑.常见的方法是使用类似iteratee的功能.有很多不错的图书馆:管道,管道等.在大多数情况下,他们会做这件事.但是AFAIK它们(除了,可能是管道)受到处理顺序的限制.
但考虑一个日志查看器示例:人类可能希望随机来回漫步.他也可以放大和缩小.我担心迭代者在这里无能为力.
一个简单的解决方案可能如下所示:
-- True is for 'right', 'up', etc. and vice versa
type Direction = Bool
class Frame (f :: * -> *) where
type Dimension f :: *
type Origin f :: * -> *
grow', shrink' move' :: Monad m => Dimension f -> Direction -> f a -> m (f a)
move' dim dir f = grow' dim dir f >>= shrink' dim (not dir)
liftF' :: (Origin f a -> b) -> f a -> b
class Frame f => MFrame f where
liftMF' :: (Origin f a -> (b, Origin f a)) -> f a -> (b, f a)
-- Example instance: infinite stream.
data LF a = LF [a] [a] [a]
instance Frame LF where
type Dimension LF = () -- We have only one dimension to move in...
type Origin LF = [] -- User see piece of stream as a plain list
liftF' f (LF _ m _) = f m
grow' () True (LF l m (h:r)) = return $ LF l (m++[h]) r
...
Run Code Online (Sandbox Code Playgroud)
然后可以将其包装到StateT中,依此类推.所以,问题:
0)我是否完全错过了迭代的重点,它们适用于此?
1)我刚刚重新发明了一个众所周知的车轮吗?
2)很明显,增长和缩小操作非常无效,因为它们的复杂性与帧大小成正比.有没有更好的方法来扩展这样的拉链?
你想要镜头,特别是sequenceOf功能.以下是3元组目标加载的示例:
sequenceOf _2 :: (IO a, IO b, IO c) -> IO (IO a, b, IO c)
Run Code Online (Sandbox Code Playgroud)
sequenceOf将镜头带到包含加载操作的多态字段,运行操作,然后用操作结果替换该字段.sequenceOf只需在要加载的字段中使类型具有多态性,就可以在自己的自定义类型上使用,如下所示:
data Asset a b = Asset
{ _art :: a
, _sound :: b
}
Run Code Online (Sandbox Code Playgroud)
...并且还使你的镜头使用完整的四种类型参数(这是它们存在的一个原因):
art :: Lens (Asset a1 b) (Asset a2 b) a1 a2
art k (Asset x y) = fmap (\x' -> Asset x' y) (k x)
sound :: Lens (Asset a b1) (Asset a b2) b1 b2
sound k (Asset x y) = fmap (\y' -> Asset x y') (k y)
Run Code Online (Sandbox Code Playgroud)
...或者您可以使用自动生成镜头makeLenses,它们将足够通用.
然后你可以写:
sequenceOf art :: Asset (IO Art) b -> IO (Asset Art b)
Run Code Online (Sandbox Code Playgroud)
...加载多个资产就像组成Kleisli箭头一样简单::
sequenceOf art >=> sequenceOf sound
:: Asset (IO Art) (IO Sound) -> IO (Asset Art Sound)
Run Code Online (Sandbox Code Playgroud)
...当然,您可以嵌套资产并组合镜头以达到嵌套资产,一切仍然"正常".
现在你有一个纯Asset类型,你可以使用纯函数处理,所有加载逻辑都被分解为镜头.
我在手机上写了这个,所以可能有几个错误,但我稍后会修复它们.
| 归档时间: |
|
| 查看次数: |
187 次 |
| 最近记录: |