4

クラス のストリーム関数(SF)のleft/メソッドを次のように定義しました。rightArrowChoicenewtype 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 (:))))
4

1 に答える 1

7

ArrowChoiceあなたのインスタンスは正しくないと思います。

delay関数はストリームを受け取り、最初の要素を置き換えることに注意してください。重要なのは、すべての要素を同じように扱うわけではないということです。Leftここで、次の定義について考えてみましょう。

left (SF f) = SF $ map (either (\x -> Left . head $ f [x]) Right)

これが流れ関数全体の本質fであることに注意してください。したがって、流れの位置によって動作が異なる場合があります。次に、この関数は、同次関数をそのストリームにマッピングleftする新しいストリーム関数を作成します。ここで、各要素は(sの場合)渡されるか、入力ストリーム関数が実行されるシングルトンリストにリフトされます。Right

ではなくdelay、代わりに次の関数を検討してください。

skip = SF $ drop 1

これにより、ストリームの最初の要素が完全に削除leftされ、シングルトンリストで毎回独立して入力が実行されるため、すべての要素が完全に除外されますLeft。おそらくあなたが望むものではありません。

Leftむしろ、ストリームをそのコンポーネントとコンポーネントに分割しRight、入力ストリーム関数をsのストリーム全体Leftに適用してから、左と右を元の順序と同じ順序でマージするなどの操作を行う必要があります。

ある種の練習としてこれをやっているような印象を受けるので、解決策を完全に書き出すだけで楽しみを損なうことはありません。しかし、私のコードは確か[[0,0,0],[1,2,3],[4,5,6]]にあなたの例を示していると言います。


私のテストコードを見たい場合は、以下にあります。(shh、それは隠れています)

インスタンスArrowChoiceSFここで
     left(SF f)= SF $ \ xs-> let(ls、rs)= partitionEithers xs
                               マージxs(f ls)rs
 
 マージ(左_:xs)(l:ls)rs =左l:マージxs ls rs
 マージ(右_:xs)ls(r:rs)=右r:マージxs ls rs
 マージ___ = []
 

于 2011-08-01T05:46:10.620 に答える