7

私はファンクター、アプリケーションファンクターに注目しています…行きたい場所にたどり着く方法はわかりませんが、タイプに従うことで私はもっと近づくはずだと感じています。

map2タプルの最初の要素にのみ適用される-alikeを作成する簡単な方法はありますか?firstから取っControl.Arrowて使用するとArrow (->)、これでうまくいきます。

map . first :: (b -> c) -> [(b, d)] -> [(c, d)]

私の唯一の懸念は、矢についての本当の直感をまだ得ていないということです。ですから、これを続ければ、遅かれ早かれ深海にいることに気付くでしょう。さらに、これは一般化できないかなり便利なケースのようです。

ファンクターやモナドなどから何かを使って同じ機能を手に入れながら、欲しいものの核心をつかむことはできますか?私はいじっていました

\f -> map (f `on` fst)

-アイデアのようですが、そこに到達することはできませんでした。

4

5 に答える 5

10

矢印には、タプルを操作するための優れたコンビネータがあります。それらは、欠落しているタプル関数とほぼ考えることができます。

だから例えば

> :t \f -> map (f *** id)
  :: (b -> c) -> [(b, c')] -> [(c, c')]

最初のコンポーネントをマッピングするための便利な方法です。

于 2012-05-30T14:55:49.040 に答える
5

この種のことを行うことができる別の抽象化は、バイファンクターです。エドワード・クメットには、bifunctorsと呼ばれるパッケージがあります。 Data.Bifunctorには、まさにこの機能のための型クラスがあり、たとえば2タプルが含まれています。

于 2012-05-30T15:03:18.823 に答える
2

したがって、タイプの関数を探しています(a -> b) -> (a,c) -> (b,c)。あなたがただ書くことができればそれは素晴らしいでしょう

{-# LANGUAGE TupleSections #-}
instance Functor (,c) where
    fmap f (x,c) = (f x, c)

ただし、残念ながら、タプルセクションは値レベルでのみ機能します。これに理論的な理由があるかどうかはわかりません。高次型の統一を台無しにしていると思います。

Hayooは、関数が呼び出されるパッケージData.Tuple.HTmapFstを思い付きました。

bifunctors(BiFunctorインスタンスは(,)本当にあなたが望むことを実行し、それ以上は何もしません)または矢印に上がらなければ、少なくとも私が知っている、あなたが望むものを取得する方法はありません。

于 2012-05-30T20:08:26.677 に答える
2

問題は、方法が多すぎることだと思います-ダニエル・ワーグナーのアドバイスで行くと思います-しかし、ここにあなたの娯楽のための別のものがあります:

{-#LANGUAGE DeriveFunctor, MultiParamTypeClasses  #-}
import Control.Newtype

newtype P a b = P {p:: (b, a)} deriving (Show,Eq,Ord,Functor)
instance Newtype (P a b) (b,a) where pack = P; unpack = p

 -- *Main> fmap even ("Hi",4)
 -- ("Hi",True)
 -- *Main> map (fmap even) [("Hi",4),("Bye",5)]
 -- [("Hi",True),("Bye",False)]
 -- *Main> under P (fmap even) (4,"Hi")
 -- (True,"Hi")
 -- *Main> map (under P (fmap even) ) [(4,"Hi"),(5,"Bye")]
 -- [(True,"Hi"),(False,"Bye")]
于 2012-05-30T21:15:38.127 に答える
1

さて、BiFunctorパッケージがあります。

または、逆ペアタイプを使用することもできます。

data Flip a b = Flip b a

instance Functor (Flip a) where
  fmap f (Flip x y) = Flip (f x) y
于 2012-05-30T15:13:06.783 に答える