Haskell Is(map f)==concatMap(map f.([]))?

Haskell Is(map f)==concatMap(map f.([]))?,haskell,arrows,Haskell,Arrows,我为ArrowChoice类的流函数(SF)定义了left/right方法,如下所示: 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 $

我为
ArrowChoice
类的流函数(SF)定义了
left
/
right
方法,如下所示:
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 (:))))

我认为您的
箭头选择
实例不正确

请注意,
delay
函数接受一个流并替换第一个元素;关键是,它并不是一视同仁地对待所有元素。现在,考虑你对代码的定义>左< /代码>:

left (SF f) = SF $ map (either (\x -> Left . head $ f [x]) Right)
请注意,
f
是整个流函数的核心,因此根据流位置的不同,其行为可能会有所不同。然后,
left
函数创建一个新的流函数,该流函数将齐次函数映射到其流上,其中每个元素要么被传递(对于
Right
s),要么被提升到运行输入流函数的单例列表

而不是<代码>延迟< /代码>,考虑下面的函数:

skip = SF $ drop 1
这将完全删除流的第一个元素,并且由于
left
每次在单例列表上独立运行其输入,因此这将完全过滤掉所有
left
s!可能不是你想要的

相反,您需要将流划分为
Left
Right
组件,将输入流函数应用于整个
Left
s流,然后按照原来的顺序将Left和Right合并在一起

我得到的印象是,你这样做是作为一种锻炼,所以我不会简单地把解决方案完整地写出来而破坏乐趣。但我要说的是,我的代码确实给出了你例子中的
[[0,0,0],[1,2,3],[4,5,6]


如果你真的想看我的测试代码,它在下面。(嘘,它藏起来了)

实例arrowhere 左(SF f)=SF$\xs->let(ls,rs)=分区 在合并xs(f ls)rs中 合并(左uuxS)(l:ls)rs=左l:merge xs ls rs 合并(右:X)ls(r:rs)=右r:merge xs ls rs 合并


我仍然对你选择的标题感到困惑(答案是响亮的‘是’)-你愿意为我们这些最后一次使用
Arrow
s是在青铜时代的人扩展一下你的问题吗?@kizzx2:我也没有,但在这里似乎合适。我知道有一个“扰流板”功能,在发布答案和添加隐藏代码之间大约8分钟的时间是我花了多长时间来找出如何正确显示它。。。 instance ArrowChoice SF where left (SF f) = SF $ \xs -> let (ls, rs) = partitionEithers xs in merge xs (f ls) rs merge (Left _:xs) (l:ls) rs = Left l : merge xs ls rs merge (Right _:xs) ls (r:rs) = Right r : merge xs ls rs merge _ _ _ = []