Haskell functorları neden hedef kategorilerinde sadece türetilmiş tiplere sahip?


12

Haskell'de, Functor tipeclass functor aşağıdaki gibi tanımlanır (bkz. Örneğin Haskell wiki ):

class Functor (f :: * -> *) where
  fmap :: (a -> b) -> f a -> f b 

Bildiğim kadarıyla (hatam varsa düzeltin lütfen) anladığımız kadarıyla böyle bir funktor sadece kategori türüdür yapıcısı kullanılarak inşa hedef kategorisi, örneğin olarak sahip olabilir [], Maybediğer yandan, vb biri herhangi bir kategori olan functors düşünebilirler bir functor hedefi olarak, örneğin tüm Haskell tiplerinin kategorisi. Örneğin, Intyalnızca Maybe Intveya değil, bir işlevin hedef kategorisindeki bir nesne olabilir [Int].

Haskell functorlarındaki bu kısıtlamanın motivasyonu nedir?


4
Basitlik? Haskell'in birinci sınıf tür işlevleri yoktur, bu nedenle tüm işlevler gerçekten yalnızca tür yapıcılarıdır.
Daniel Gratzer

2
@jozefg: Cehaletimi affedin: "birinci sınıf tip fonksiyonlar" nelerdir?
Giorgio

4
Yani bu fonksiyonda bir fhakkın etrafına fırlatıyoruz ? Ve senaryonuzda, fnormal bir Haskell işlevi gibi olmalı ve türleri türlerle eşleştirmelisiniz. Haskell'de türüne izin verilen tek şey * -> *tip kuruculardır. Tip aileler daha geneldir, ancak her zaman tam olarak uygulanmalıdırlar
Daniel Gratzer


@jozefg: Bu soruyu zaman zaman tekrar tekrar düşünüyorum. Haskell kısıtlamasının functorların ifade gücünü etkilemediğini düşünüyorum. Örneğin, liste işlevine izomorfik olan ancak eşleme yapmayan bir işleve sahip olduğumuzu varsayalım, örneğin Int -> [Int] değil, Int -> <tür yapıcısı olmayan süslü tip>. Sonra sanırım <tür yapıcı olmadan süslü tip> [Int] için izomorfik olduğunu kanıtlayabilir. Bu nedenle, bir tür oluşturucu kullanılarak tanımlanan nesnelerin seçilmesi uygundur ve ifade gücünü feda etmez.
Giorgio

Yanıtlar:


1

Hiç bir kısıtlama yok! Tip yapıcılar için kategori-teorik temeli öğrenmeye başladığımda, bu nokta beni de karıştırdı. Buna ulaşacağız. Ama önce biraz karışıklık çıkarmama izin verin. Bu iki alıntı:

böyle bir işlev yalnızca hedef kategori olarak bir tür oluşturucu kullanılarak oluşturulmuş bir kategoriye sahip olabilir

ve

herhangi bir kategoriye sahip functorları bir functor hedefi olarak düşünebilir, örneğin tüm Haskell tiplerinin kategorisi

bir işlevin ne olduğunu yanlış anladığınızı gösterin (veya en azından terminolojiyi kötüye kullandığınızı).

Functors yok inşa kategoriler. Bir işlev, kategoriler arasındaki bir eşlemedir . Functors, kaynak kategorisindeki nesneleri ve morfizmleri (türleri ve işlevleri) hedef kategorideki nesneye ve morfizmlere getirir.

Not Bu bir funktor gerçekten olduğu anlamına gelir çifti bir nesne üzerinde haritalama: eşleme F_obj morfizimler ve haritalama F_morph . Haskell'de, işlevcinin nesne kısmı F_obj , tür yapıcısının adıdır (örneğin List), morfizm kısmı işlevdir fmap( fmapherhangi bir ifadede bahsettiğimiz şeyi sıralamak Haskell derleyicisine bağlıdır ). Dolayısıyla Listbunun bir işlev olduğunu söyleyemeyiz ; Sadece kombinasyonu Listve fmapbir funktoru olduğunu. Yine de insanlar gösterimi kötüye kullanıyor; programcılar çağrı Listkategori teorisyenleri funktor her iki kesiminde başvurmak için aynı sembol kullanırken, bir functor.

Ayrıca, programlamada hemen hemen tüm işlevler endofunktörlerdir , yani kaynak ve hedef kategori aynıdır - dilimizdeki tüm türlerin kategorisi. Bu kategoriye Tür diyelim . Tip üzerindeki bir endofunctor F , T tipini başka bir FT tipine ve T -> S fonksiyonunu başka bir FT -> FS fonksiyonuna eşler . Bu haritalama elbette fonktor yasalarına uymak zorundadır.

ListÖrnek olarak kullanarak : birlikte List : Type -> Typebir işlev fmap: (a -> b) -> (List a -> List b)oluşturan bir tür yapıcı ve bir fonksiyonumuz var . T

Temizlenecek son bir nokta var. Yazma List intgelmez oluşturmak tamsayılar listelerinin yeni bir tür. Bu tür zaten vardı . Bizim kategorisinde bir nesne oldu Tip . List Intsadece bunu ifade etmenin bir yoludur.

Şimdi, bir işlevin neden bir türü, diyelim Intveya ile eşleyemediğini merak ediyorsunuz String. Ama olabilir! Kişi sadece kimlik işlevini kullanmak zorundadır. Herhangi bir C kategorisi için , kimlik işlevi her nesneyi kendisine ve biçimselliği kendine eşler. Bu eşlemenin işlev yasalarını karşıladığını doğrulamak kolaydır. Haskell'de bu, id : * -> *her türü kendi kendine eşleyen bir tür oluşturucu olacaktır . Örneğin, olarak id intdeğerlendirir int.

Dahası, tüm tipleri tek bir tiple eşleştiren sabit functorlar bile oluşturulabilir . Örneğin, tüm türlerin ToInt : * -> *bulunduğu ve tüm morfizmleri tamsayı kimlik işleviyle eşleyen işlev: ToInt a = intafmap f = \x -> x


Cevabınız için teşekkürler, bu soru iki yıldan daha eski. "Functors kategori oluşturmaz.": Bunu söylemedim. Ben hedef kategorisi formu olması gerekir nerede fanktorlar, iki kategoriyi harita söyledi f a, folduğunu, biliyorum kadarıyla, bir tür yapıcı. Kategori teorisinden hatırladığım kadarıyla, bu bir tür kanonik temsil olmalıdır (bir kategori kategorisindeki ilk nesne? Belki de terminolojiyi kötüye kullanıyorum.) Her neyse, cevabınızı dikkatlice okuyacağım. Çok teşekkürler.
Giorgio

@Giorgio whoops, kaç yaşında olduğunu fark etmedim haha. Sadece "cevaplanmamış sorular" da ortaya çıktı. "Kanonik temsil" ile ne demek istediğinden emin değilim. Bildiğim kadarıyla (ve burada yanlış olabilirim), functors ve ilk / terminal nesneleri arasında bir ilişki yoktur.
16'da gardenhead

Şunu demek istiyorum: en.wikipedia.org/wiki/Initial_algebra (bkz. Bilgisayar biliminde kullanım). Haskell'de (çoğu) functorlar cebirsel veri türlerinde tanımlanır. Böyle bir işlevin hedef nesnesi bir ilk cebirdir. İlk cebir, değer yapıcıları kullanılarak oluşturulan terimler kümesine izomorfiktir. Örneğin, listeler için []ve :. Bunu kanonik temsil ile kastetmiştim.
Giorgio

Evet, bir başlangıç ​​nesnesinin ne olduğunu ve endüktif veri tiplerinin bir kategorinin F-cebirindeki başlangıç ​​nesneleri olduğunu biliyorum. Pek çok tip kurucusunun tümevarımsal olarak tanımlandığından emin olabilirsiniz. Ancak bu kesinlikle gerekli değildir . Örneğin, funktor (_, int)bir türü alır aürün tipine (a, int)ve bir işlev f : 'a -> 'biçin g : 'a * int -> 'a * intendüktif değildir.
16'da gardenhead

Şunu mu demek istedin "takes ... a function f : 'a -> 'bto g : 'a * int -> 'b * int?
Giorgio
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.