我试图使用箭头捕获对称数据处理管道,并且想知道是否可以进行双向合成。
Control.Arrow公开以下内容
-- | Left to right composition
(>>>) :: Category cat => cat a b -> cat b c -> cat a c
-- | Right to left composition
(<<<) :: Category cat => cat b c -> cat a b -> cat a c
我喜欢什么,但无法解决如何表达双向组合。类型就像。
(<^>) :: Category cat => cat (a,y) (b,z) -> cat (b,x) (c,y) -> cat (a,x) (c,z)
其中每对的第一个元素是从左到右组成,第二个元素是从右到左组成。
答案 0 :(得分:5)
这是一个涉及前向和后向功能对的类别示例。
{-# LANGUAGE TypeOperators, GADTs #-}
import Prelude hiding ((.))
import Data.Category
import Data.Category.Product
type C = (->) :**: (Op (->))
以上说明C (a,b) (c,d)
与同义(a->c, d->b)
同构。对&#34;撰写&#34;在自然方式的类别中:前向函数是向前组成的,向后函数是向后组成的。
以下是两个例子:
f :: C (String, Bool) (Int, Char)
f = length :**: Op (=='a')
注意向后函数必须如何包含在Op
中(属于&#34;对面&#34;类别)。
g :: C (Int, Char) ([Int], Maybe Char)
g = (\x->[x,x]) :**: Op (maybe 'X' id)
注意&#34;来源&#34; g
是&#34;目标&#34; f
。这确保了组合成为可能。
composed :: C (String, Bool) ([Int], Maybe Char)
composed = g . f
test :: ([Int], Bool)
test = case composed of
(forward :**: Op backward) -> (forward "abcde", backward Nothing)
-- result: ([5,5],False)
在更实际的方面,请注意Data.Category
和Control.Category
是不同的野兽:-(并且问题中提到的Control.Arrow
库使用后者。
仍然可以为Op
定义:**:
和Control.Category
。也许它已经在某个地方进行过hackage(?)。
答案 1 :(得分:2)
一些进一步的方法,最好记录为单独的答案。
第一个强加了ArrowLoop
的附加约束,并使用递归箭头do
表示法定义。
然而,从数据流的角度来看,没有发生递归。
(<->) ∷ (ArrowLoop a) ⇒ a (b,f) (c,g) → a (c,e) (d,f) → a (b,e) (d,g)
(<->) f1 f2 = proc (b, e) → do
rec
(c,g) ← f1 ↢ (b,f)
(d,f) ← f2 ↢ (c,e)
returnA ↢ (d,g)
同样可以定义为
(<->) ∷ (ArrowLoop a) ⇒ a (b,f) (c,g) → a (c,e) (d,f) → a (b,e) (d,g)
(<->) f1 f2 = proc (b, e) → do
rec
(d,f) ← f2 ↢ (c,e)
(c,g) ← f1 ↢ (b,f)
returnA ↢ (d,g)
第二种方法不是:如果这是一个理智的事情,我还没有解决。
(<->) ∷ (Arrow a) ⇒ a (b,f) (c,g) → a (c,e) (d,f) → a (b,e) (d,g)
(<->) f1 f2 = proc (b, e) → do
(c,_) ← f1 ↢ (b,undefined)
(d,_) ← f2 ↢ (c,undefined)
(_,f) ← f2 ↢ (undefined,e)
(_,g) ← f1 ↢ (undefined,f)
returnA ↢ (d,g)
以下与第二种方法相同,但在组成函数方面明确定义。
(<->) ∷ (Arrow a) ⇒ a (b,f) (c,g) → a (c,e) (d,f) → a (b,e) (d,g)
(<->) f g =
let toFst x = (x,undefined)
toSnd x = (undefined,x)
in
(arr toFst ⋙ f ⋙ arr fst ⋙ arr toFst ⋙ g ⋙ arr fst) ⁂
(arr snd ⋘ f ⋘ arr toSnd ⋘ arr snd ⋘ g ⋘ arr toSnd)