apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "service"
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# The configs to allow all IPs access via https and allow some IPs in
# security whitelist access via http
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($https) {
set $allow_ip true;
}
if ($remote_addr ~ (x.x.x.x|y.y.y.y) {
set $allow_ip true;
}
if ($allow_ip != true) {
return 403;
}
spec:
tls:
- hosts:
- "example.com"
secretName: example.name
rules:
- host: "example.com"
http:
paths:
- path: /
backend:
serviceName: service
servicePort: 80
软件包具有非常有效的vector-0.1
实现(Data.Vector.Stream
):
Stream
data Step s a = Yield a s
| Skip s
| Done
-- | The type of fusible streams
data Stream a = forall s. Stream (s -> Step s a) s Size
的较新版本将其扩展为Monadic版本Data.Vector.Fusion.Stream.Monadic
,但为简单起见,让我们使用较旧的非Monadic版本。
vector
很自然是Stream
和Functor
的实例:
Foldable
作为流,它也应该是Traversable
的实例,不是吗?至少乍一看,这看起来很简单。我们需要
instance Foldable Stream where
foldMap f s = foldl' (\a b -> a <> (f b)) mempty s
开始为
sequenceA :: Applicative f => Stream (f a) -> f (Stream a)
sequenceA (Stream step s) = Stream <$> step' <*> (pure s) where
step' = ...
是从<*>
下面“拉出”适用f
的唯一方法。现在,Stream
应该是
step'
,我们有一个
step' :: f (s -> Step s a)
我所知道的是step :: s -> Step s (f a)
是f
(和Applicative
)。但是Functor
“推入” <*>
(f
),而在这里我需要正好相反,可以说是co-<*> :: f(a->b)->(f a->f b)
。
拥有<*>
实例对于我的任何工作都不是至关重要的,从性能的角度来看,它甚至是不可取的。但令我感到困惑的是,我并不真正理解为什么Traversable
不会是Stream
。缺少使Traversable
成为Stream
的哪些结构元素?
答案 0 :(得分:5)
这是可遍历的,但不是非常有趣的方式。因为它既允许fromList
也允许toList
,所以我们有
sequenceA = fmap fromList . sequenceA . toList
您实际上不能做更多有趣的事情:您有一个Stream (f a)
,但希望产生f (Stream a)
。由于您的视频流与列表同构,因此要使f
中的效果达到最外层,您必须遍历流中的每个项目,并合并每个项目的效果,最后构造一个使嵌入其中的对象鹦鹉化的流应用结构,顺序与您看到它们的顺序相同。
如果愿意,可以使用Stream模块中的其他功能自己重新实现此功能,但是它基本上是相同的。特别是,它也很懒。一种方法是:
sequenceA (Stream step init) = case step init of
Yield x s -> cons <$> x <*> sequenceA (Stream step s)
Skip s -> sequenceA $ Stream step s
Done -> pure (Stream (const Done) ())
正如您所看到的,与尝试的最大不同之处在于,您应该使用Yield案例中的x
值-这是合并其效果的唯一方法,因为如您所述,您无法提取f a
中的值,只能将其他值压入一个。令人高兴的是,这毕竟是您想要做的!在进入结构的有趣部分之前,您什么都无法fmap,这意味着首先调用step s
来掌握其效果。
您根本不需要pure s
,因为您正在构建具有新内部状态的新Stream,它与您消耗的Stream无关。而且,您已经可以利用范围内的s
值:调用step
!
一旦您已经编写了几个流消耗函数(我是通过手动实现Foldable和Functor发现的),这种方法就很自然了。消耗流的唯一可能方法是在step s
上进行大小写匹配,如果您以此开头,则避开了分散您注意力的红色鲱鱼。