2011-06-22 24 views
15

純粋な関数をコンテナにマッピングするか、それを介してアプリケーション/モナドのアクションをシーケンシングするための関数が必要です。 ( - (>)と、我々は我々が(Data.Taversableから)持って単項配列決定のためにFunctorは(a - > b) - >(f a - > f b)であり、(cカテゴリ)=> c a b - > c(f a)(f b)とは何か?

fmap :: Functor f => (a -> b) -> (f a -> f b) 

を持っている純粋なマッピング

mapKleisli :: (Traversable f, Monad m) => Kleisli m a b -> Kleisli m (f a) (f b) 
mapKleisli = Kleisli . mapM . runKleisli 

に似て

mapM :: (Traversable f, Monad m) => (a -> m b) -> (f a -> m (f b)) 

のために我々は両方知っていますKleisli m)はカテゴリ(および矢印)です。したがって、一般化するのは当然です。

mapCategory :: (X f, Category c) => c a b -> c (f a) (f b) 

このようなクラスXは、同様の方法で知っていますか?たぶん、どこかでハッキングされていますか?私はgoogle/hayooにしようとしましたが、適切なものは見つかりませんでした。

更新:

今私は必要なものをよく知っています。 Kleisliの矢印と( - >)の両方はMonAppほど強力なArrowApplyのインスタンスです。私は純粋な機能のためのアイデンティティを持つだけで、通常のApplicativeベースTraversableのを、使用することができ

{-# LANGUAGE TypeOperators #-} 

import Prelude hiding (id, (.), mapM) 
import Control.Arrow 
import Control.Category 

class Traversable f where 
    traverse :: ArrowApply (~>) => f a -> (a ~> b) ~> f b 

mapArrow :: (ArrowApply (~>), Traversable f) => a ~> b -> f a ~> f b 
mapArrow a = arr (\x -> (traverse x, a)) >>> app 

instance Traversable Maybe where 
    traverse Nothing = arr (const Nothing) 
    traverse (Just x) = arr (\a -> (a, x)) >>> app >>> arr Just 

instance Traversable [] where 
    traverse [] = arr (const []) 
    traverse (x : xs) = undefined -- this is hard! 

が、私はそれが良いかわからない:私はTravesableのこの矢印ベースのバージョンを思い付きました。モナド行動の特殊なケースとしての純粋な機能を考えることは奇妙です。純粋な関数とモナドのアクションの両方を、いくつかのアクションクラス(Category/Arrow/ArrowApply)のインスタンスとして解釈することは、私にとってもっと簡単です。

質問:[]のインスタンスを終了しますか? ArrowApply vs Monadについて私の意見はありますか?

答えて

10

あなたは「いくつかのクラスX」を求めていますが、このクラスのほとんどの(またはたぶん唯一の)正しい名前が「Functor」になるはずです。あなたが望むのは、(->)に限らず、任意のCategoryインスタンスに対して定義されたファンクタクラスです。

もちろん、あなたの定義は、カテゴリから(endo)ファンクタに限定され、インスタンスを与える型コンストラクタによって定義されたサブカテゴリに限定されます。あなたは少しさらに一般化した場合、あなたにa type class something like this oneを与え、二つのカテゴリーが同じであるためには何の理由もありません:

class (Category r, Category t) => Functor f r t | f r -> t, f t -> r where 
    fmap :: r a b -> t (f a) (f b) 

これはまあ、まだ圏論におけるファンクタの完全な概念対ひどく限られているが、 。

これはまだ(->)型のコンストラクタを持っていることに気付くのも面白いです。なぜなら、ソースカテゴリとターゲットカテゴリを任意のインスタンスでモデル化していても、全体(とくにファンクタ自体)は、ある意味ではまだHaskにあります。つまり、カテゴリは(->)に関連付けられています。ファンクタのもう半分(パーツマッピングオブジェクト)は、おおよそ、タイプコンストラクタf* -> *(->)です。

+0

お返事ありがとうございますが、このケースでは私は理論よりも実際的な興味があります。 [カテゴリパッケージ内](http://hackage.haskell.org/packages/archive/categories/0.56.0/doc/html/Control-Categorical-Functor。html)私たちは基本クラス(クラス自体を除く)と比較して何も新しいものを与えない、(Endo)Functorインスタンス( - >)カテゴリのみを持っています。 – modular

+0

@ user713303:あなたは自分のインスタンスを自由に書くことができます。たとえば、あなたの質問で実証したように、Kleisliの矢印の場合は非常に簡単です。 –

+1

実用的で便利なインスタンスを念頭に置いているのであれば、なぜ貢献しないのですか?パッケージの[githubページ](https://github.com/ekmett/categories)です。 –

関連する問題