- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我重新发明了某种“状态箭头”:
import Prelude hiding (id, (.))
import Control.Monad.State
import Control.Arrow
import Control.Category
data StateA s a b = StateA {runStateA :: s -> a -> (b, s)}
instance Category (StateA s) where
id = StateA (\s a -> (a, s))
(StateA f) . (StateA g) = StateA $ \s x -> let (b, s') = g s x in f s' b
instance Arrow (StateA s) where
arr f = StateA $ \s a -> (f a, s)
first (StateA f) = StateA $ \s (b, d) -> let (c, s') = f s b in ((c, d), s)
put' :: s -> StateA s b ()
put' s = StateA $ \_ _ -> ((), s)
get' :: StateA s b s
get' = StateA $ \s _ -> (s, s)
merge :: (s -> s -> s) -> StateA s a b -> StateA s a c -> StateA s a (b, c)
merge f (StateA a) (StateA b) = StateA $ \s x ->
let (ra, sa) = a s x
(rb, sb) = b s x
in ((ra, rb), f sa sb)
test = (flip runStateA) s bar
where bar = ((put' 7) >>> get') &&& get'
看起来这个定义如我所愿:至少测试 3 5 产生
((7,3), 3)
请注意,此行为有意与包裹在箭头中的普通 State monad 不同,如下所示:
liftKC = Kleisli . const
putM :: a -> Kleisli (State a) b ()
putM = liftKC . put
getM :: Kleisli (State a) b a
getM = liftKC get
foo :: (Num a) => Kleisli (State a) a (a, a)
foo = (putM 7 >>> getM) &&& getM
testKleisli a b = (flip runState) a $
(flip runKleisli) b foo
as testKleisli 3 5 返回
((7, 7), 7).
重点是,人们可以分别操纵某些“计算的并行分支”中的状态,然后以某种方式将其合并。
我不熟悉箭头表示法,但它在这里很不方便:看起来它为每个计算创建了新的“分支”。是否可以使用箭头符号重写“bar”函数(来自测试的 where 子句)?
最佳答案
让我们画一张图
bar = ((put' 7) >>> get') &&& get'
让我们了解如何用箭头表示法编写它。
就像一元 do
一样符号,proc
表示法引入了命名变量,取代了组合符,例如 >>=
显式传递值。
无论如何,我们可以看到我们需要提供输入,x
,向两侧,给出:
bar' = proc x -> do
wasput <- put' 7 >>> get' -< x
justgot <- get' -< x
returnA -< (wasput,justgot)
或者如果我们希望所有内容都从右到左,则等效
bar'' = proc x -> do
wasput <- get' <<< put' 7 -< x
justgot <- get' -< x
returnA -< (wasput,justgot)
我会重构test
对于多次测试:
test s b = (flip runStateA) s b
所以我们得到
ghci> test bar 3 5
((7,3),3)
ghci> test bar' 3 5
((7,3),3)
ghci> test bar'' 3 5
((7,3),3)
>>>
吗? ?我们可能会想将 (>>>)
分解出来。 :
bar''' = proc x -> do
put7 <- put' 7 -< x
wasput <- get' -< put7
justgot <- get' -< x
returnA -< (wasput,justgot)
哎呀,不:
ghci> test bar''' 3 5
((3,3),3)
正如您所指出的,您的状态是本地化的,并且 put' 7
不会连接到 get'
,所以我们还没有设法摆脱 >>>
或<<<
组合器。
我不禁觉得这违反了阿罗定律或其他定律。嗯...
我花了一段时间才找到答案,但经过大量的手工脱糖和皱着眉头看图表后,我发现了一个箭头法则正盯着我,你的实例会崩溃:
first (f >>> g) = first f >>> first g
如果我们定义
dup :: Arrow a => a t (t, t)
dup = arr (\x -> (x,x))
我们得到
ghci> test (dup >>> (first (put' 7 >>> get'))) 1 3
((7,3),1)
ghci> test (dup >>> (first (put' 7) >>> first get')) 1 3
((1,3),1)
这是因为 put' 7
中的本地化状态在第二个示例中,没有进入第二个 first
,如果你能遵循所有这些第一和第二!
您发现箭头表示法对于您的箭头实例不太有用,因为它假设可以通过不成立的定律进行转换。
可悲的是,虽然确实非常有趣,而且非常有趣,但它不是真正的《绿箭侠》。
关于haskell - 是否可以使用 ghc 箭头表示法重写此示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21857635/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
我有实体: @Entity @Table(name = "CARDS") public class Card { @ManyToOne @JoinColumn(name = "PERSON_I
我正在尝试计算二维多边形的表面法线。我正在使用 OpenGL wiki 中的 Newell 方法来计算表面法线。 https://www.opengl.org/wiki/Calculating_a_S
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 7 年前。 Improve
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我这里有以下 XML: Visa, Mastercard, , , , 0, Discover, American Express siteonly, Buyer Pay
即将发生的 Google 政策变更迫使我们实现一个对话框,以通知欧盟用户有关 Cookie/设备标识符用于广告和分析的情况。我只想向欧盟用户显示此对话框。我不想使用额外的权限(例如 android.p
本文分享自华为云社区《华为大咖说 | 企业应用AI大模型的“道、法、术” ——道:认知篇》,作者:华为云PaaS服务小智。 本期核心观点 上车:AGI是未来5~10年内,每个人都无法回避的技
我有一个与酒精相关的网站,需要先验证年龄,然后才能让他们进入该网站。我使用 HttpModule 来执行此操作,该模块检查 cookie,如果未设置,我会将它们重定向到验证页面。我验证他们的年龄并存储
在欧盟,我们有一项法律,要求网页请求存储 cookie 的许可。我们大多数人都了解 cookie 并同意它们,但仍然被迫在任何地方明确接受它们。所以我计划编写这个附加组件(ff & chrome),它
以下在 C 和/或 C++ 中是否合法? void fn(); inline void fn() { /*Do something here*/ } 让我担心的是,第一个声明看起来暗示函数将被定义
我是一名优秀的程序员,十分优秀!