6

私はこのようなことをする方法を見つけようとしています:

(head, last) `someFunction` [1, 2, 3]

タプル(1, 3)を出力として生成します。

理論的にはアプリケーションファンクターに似ているように見えますが、少し逆になっています。これを行う(または何らかの方法で作成する)同様の関数があると思いますが、それを見つけられない/理解できないようです。

私はこのような関数を定義しようとしました:

fmap' :: ((a -> b), (a -> b)) -> [a] -> (b, b)
fmap' (f1, f2) xs = (f1 xs, f2 xs)

しかし、GHCは実際にはこれをコンパイルしません。

どんな助けでも素晴らしいでしょう。ありがとう!

編集(1年後!):

型アノテーションfmap'が間違っていたため、コンパイルできませんでした。明らかに、私がやっていたことを行うためのより良い方法がありますが、fmap'代わりに私のタイプは次のようになります。

fmap' :: ((a -> b), (a -> b)) -> a -> (b, b)

その場合、コンパイルして正常に実行されます。

4

4 に答える 4

15

矢印でできると思います。

head &&& last $ [1,2,3]

を返し(1,3)ます。

于 2012-07-27T19:38:30.400 に答える
9

理論的にはアプリケーションファンクターに似ているように見えますが、少し逆になっています。

実際、それは退屈な古いフォワードのアプリケーションファンクターです。具体的には、リーダー((->) r)

Prelude Control.Applicative> liftA2 (,) head last [1,2,3]
(1,3)

または、そのようなことに興味がある場合:

Prelude Control.Applicative> let sequenceA [] = pure []; sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
Prelude Control.Applicative> [head, last] `sequenceA` [1,2,3]
[1,3]
于 2012-07-27T19:47:42.983 に答える
4

タイプfmap'が間違っています。そのはず

fmap' :: ([a] -> b, [a] -> b) -> [a] -> (b, b)

または、より一般化することができます

fmap' :: (a -> b, a -> c) -> a -> (b, c)

それは実際には似ていませんfmap :: (a -> b) -> f a -> f b

于 2012-07-27T19:20:01.110 に答える
3

この状況で試すことは、型署名を省略して、GHCが推測するものを確認することです。

そうしてGHCiに質問:t fmap'すると、署名が生成されます

fmap' :: (t2 -> t, t2 -> t1) -> t2 -> (t, t1)

これはKennyTMの一般化されたバージョンと同じであり、探している動作を提供します。

于 2012-07-27T19:32:50.853 に答える