我有这个简单的“箭头”:
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 ">"─┘
那应该解释一下。