我有这个简单的“箭头”:
std::unique
std::set<>
返回:
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
为什么我得到这2个结果?即使查看xform = ((prepend "<") >>> (append ">")) <+> ((prepend "{") >>> (append "}"))
s(作为代码中的注释)也无济于事。
答案 0 :(得分:4)
让我们再说一点:
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 ">"─┘
这应该解释一下。
答案 1 :(得分:4)
从您的问题中不清楚您期望它做什么。如果这个答案仍然没有帮助,写下您希望代码做的事情将有助于我们理解您的思考方式。
您正在使用的箭头是Kleisli []
- 即列表monad上的箭头。作为monad的列表是一个非确定性抽象 - 也就是说,列表表现得像可能性的集合。
Kliesli [] a b
类型相当于a -> [b]
,被视为monadic函数,即:它需要一个输入并返回许多可能的输出。
<+>
做的是通过每个参数转换输入,然后结合可能性。所以如果你运行箭头:
arr id <+> arr reverse
输入"hello"
,您将得到两个答案:
hello
olleh
如果你用任何东西组成,每种可能性都将被组成:
prepend "<" >>> (arr id <+> arr reverse)
然后你会得到
<hello
olleh<
因此正在考虑<+>
的每个替代方案&#34;并行&#34;。 <
出现在第二行的原因是因为输入arr reverse
已经获得"<"
前置。相比之下,如果你做了
(arr id <+> arr reverse) >>> prepend "<"
然后你得到
<hello
<olleh
这是有道理的,为什么你得到你现在做的输出?