我有这个简单的“箭头”:

main = do
        let
        -- arr :: (Arrow a) => (b -> c) -> a b c
        -- (>>>) :: Category cat => cat a b -> cat b c -> cat a c
        -- (<+>) :: ArrowPlus a => a b c -> a b c -> a b c
        -- infixr 5 <+>
        -- infixr 1 >>>
        -- runKleisli :: Kleisli m a b -> a -> m b
          prepend x = arr (x ++)
          append  x = arr (++ x)

          xform = (prepend "<") >>> (append ">") <+> (prepend "{") >>> (append "}")
          xs = ["foobar"] >>= (runKleisli xform)
        mapM_ putStrLn xs


<+>返回:

<foobar>}
{<foobar}


如果我将xform替换为:

xform = ((prepend "<") >>> (append ">")) <+> ((prepend "{") >>> (append "}"))


我得到:

<foobar>
{foobar}


为什么我得到这2个结果?即使查看infixr(作为代码中的注释)也无济于事。

最佳答案

让我们再写一点:

xform = prepend "<" >>> append ">" <+> prepend "<" >>> append ">"
xform' = (prepend "<" >>> append ">") <+> (prepend "<" >>> append ">")


现在,由于xform的绑定比infixr 5 <+>紧密,因此infixl 1 >>>被解析为

xform = prepend "<" >>> (append ">" <+> prepend "<") >>> append ">"


如图所示

                           ┌─append ">"──┐
     ──────prepend "<"─────<             +>═══append ">"═════▶
                           └─prepend "<"─┘


xform'仅对应于

            ┌─prepend "<"──append ">"─┐
     ───────<                         +>════▶
            └─prepend "<"──append ">"─┘


那应该解释一下。

10-06 02:44