1

だから私は、私が使用したいいくつかの Haskell コードを持っていData.Setます。基本的に、私は代替案をあまり調べておらず、Ord の要素を重複なく格納するための構造が必要だったからです。

個々の要素のセットに対してモナド操作を実行できるように、Data.Set の mapM のようなものが必要な状況になりました。私はすでにHayooで次のようなタイプを検索しました(a -> m b) -> Set a -> m (Set b)が、有用なものは見つかりませんでした.

またData.Traversable、[]、Maybe、および (Map k) のインスタンスがあり、Set のインスタンスがないことを確認するためだけに調べました。

だから私の質問は:

  1. Data.Set に Set の mapM がないのはなぜですか?
  2. 私が見逃したmapMのようなものを提供するパッケージはすでにありますか?
  3. Set に mapM を使用するのはお勧めできませんか? (なぜ、そして代替手段は何ですか?)
4

2 に答える 2

8

主な問題は、ファンクタが制約されていない必要があるのに対し、制約が必要なため、 および セットがファンクタTraversableFunctorならないことが必要であることです。Ord

ただし、セットは折りたたみ式なので、結果を収集する必要がない場合はmapM_fromを使用できますData.Foldable

結果が必要な場合は、リストを介して移動できます。

fromList <$> mapM f (toList s) 
于 2012-12-05T19:13:49.083 に答える
4

あなたはレンズパッケージに興味があるかもしれません。これは、トラバーサルのより一般的な抽象化を提供します(他の多くのものの中でも)。mapMsの効率が高いという問題は解決されませんがSet、制約されたデータ型のトラバーサルを表現できます。

import Control.Lens.Traversal
import Data.Traversable (traverse)
import Data.Set (Set)
import qualified Data.Set as Set

-- forall f. Applicative f => (a -> f b) -> Set a -> f (Set b)
setTraversal :: (Ord b) => Traversal (Set a) (Set b) a b
setTraversal f = (fmap Set.fromList) . traverse f . Set.toList

main = do
    print $ mapMOf setTraversal (\x -> [x+1, x-1]) $ Set.fromList [0, 10, 20]

Set.toListのドキュメントには、リストの融合の対象であると記載されていることに注意してください。運が良ければ(問題のアプリケーションによって異なりますが)、中間リストが融合する可能性があります。

于 2012-12-05T21:00:00.647 に答える