我为类的流函数(SF)定义了left
/right
方法ArrowChoice
如下:
newtype SF a b = SF { runSF :: [a] -> [b] }
instance ArrowChoice SF where
left (SF f) =
SF $ map (either (\x -> Left . head $ f [x]) Right)
right (SF f) =
SF $ map (either Left (\x -> Right . head $ f [x]))
ghci 中的一些测试看起来一切都很好:
λ> let lst = [Left 'c', Right 2, Left 'a', Right 3, Left 't']
λ> let foo = SF $ map toUpper
λ> let bar = SF $ map (+1)
λ> runSF (left foo) lst
[Left 'C',Right 2,Left 'A',Right 3,Left 'T']
λ> runSF (right bar) lst
[Left 'c',Right 3,Left 'a',Right 4,Left 't']
但是使用它却mapA
另有说明:
λ> let delay x = SF $ init . (x:)
λ> runSF (mapA (delay 0)) [[1,2,3],[4,5,6],[7,8,9]]
[[0,0,0],[0,0,0],[0,0,0]]
正确答案应该是:
[[0,0,0],[1,2,3],[4,5,6]]
其中 mapA 定义为:
mapA :: ArrowChoice arr => arr a b -> arr [a] [b]
mapA f = arr listcase >>>
(arr (const []) ||| (f *** mapA f >>> arr (uncurry (:))))