は、多くの場合、あなたはpure
なしApplicative
のようなもの、またはMonad
のようなものを持っているが、return
なし。 semigroupoidパッケージは、これらのケースをApply
とBind
でカバーしています。今私はArrow
に関する同様の状況にありますが、意味のあるarr
関数を定義することはできませんが、他の関数は完全に意味をなさないと思います。カテゴリと矢印の間のタイプクラスは意味がありますか?
私は機能を保持し、それは逆の機能の型を定義した:
import Control.Category
data Rev a b = Rev (a -> b) (b -> a)
reverse (Rev f g) = Rev g f
apply (Rev f _) x = f x
applyReverse (Rev _ g) y = g y
compose (Rev f f') (Rev g g') = Rev ((Prelude..) f g) ((Prelude..) g' f')
instance Category Rev where
id = Rev Prelude.id Prelude.id
(.) x y = compose x y
今私はArrow
を実装することはできませんが、弱い何か:
--"Ow" is an "Arrow" without "arr"
class Category a => Ow a where
first :: a b c -> a (b,d) (c,d)
first f = stars f Control.Category.id
second :: a b c -> a (d,b) (d,c)
second f = stars Control.Category.id f
--same as (***)
stars :: a b c -> a b' c' -> a (b,b') (c,c')
...
import Control.Arrow
instance Ow Rev where
stars (Rev f f') (Rev g g') = Rev (f *** g) (f' *** g')
私は実装できないと思います&&&
と等価であり、f &&& g = arr (\b -> (b,b)) >>> f *** g
と定義され、(\b -> (b,b))
と定義されているので、これは可逆的ではありません。それでも、この弱いタイプのクラスが役に立つと思いますか?それは理論的な観点からも理にかなっていますか? 「:可逆プログラミングに矢印があると再び」:このアプローチはで調査した
「矢印」はカテゴリの定義とまったく同じですか? –
いいえ、 'Category'関数はカテゴリの定義です。私はそれを理解しているので、「カテゴリ」は同じオブジェクト(すべてのタイプ)を持っていますが、異なるモチーフを持つ** Hask **のサブカテゴリに対応しています。 'Arrow'はもっと多くの構造体を追加しますが、どのような構造体について言いたいのか分かりません。 –
@Antal S-Z:実際にはサブカテゴリではありません。 'Category'は、オブジェクトが** Hask **のオブジェクトであり、2-ary型のコンストラクタによって与えられた矢印を持つカテゴリを指定します。 'Functor'は** Hask **のサブカテゴリを記述し、その矢印は** Hask **のものであり、オブジェクトは1-ary型のコンストラクタによって与えられます。 'Applicative'は'(、) 'の単層構造を' Functor'に写像し、 '(&&&)'などは 'Category'に写像します。 'arr'は** Hask **から' Category'にファンクタを与えます。 –