2015-05-27 25 views
8

katlama fonksiyonu:Neden (+) işlevi (a -> b -> b) ile eşleşiyor?

fold :: b -> (a -> b -> b) -> [a] -> b 
fold z f []  = z 
fold z f (x:xs) = f x (fold z f xs) 

(+) fonksiyonu için tip a -> a -> a ile (a -> b -> b) maçı tipi neyi http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html

Prelude> :t (+) 
(+) :: Num a => a -> a -> a 

*Main> fold (0) (+) [1,2,3] 
6 

alınan?

Katlama tanımı, (a -> b -> b) işlev türünü kabul ettiğinden, bu, (a -> b) ilk 2 parametresinin farklı türde olması gerektiği anlamına gelir?

+0

Sadece a' ve 'Çünkü' O 'a/= b' anlamına gelmez farklı harfler b' vardır. – AJFarmar

cevap

15

Hayır, bunun anlamı her a ve b farklı olabilir, ancak farklı olması için zorunlu değildir. Senin durumunda, aynı.

Şimdi
data SomeType a b = Test a b deriving (Show) 

ghci yılında: Ters yönde düşündüğünü

+4

'çifti :: a -> b -> (a, b)' bir 'veri 'örneğinden bile daha basit olabilir. – Zeta

3

Daha basit bir örnek

noktayı iletmek. + özdeştir veya a -> b -> b, sen + tipi a -> b -> b ait bir uzmanlık olmak ve zorunda bu türlerini birleştirmek kontrol etmek istiyorum eşleşip Sen kontrol etmek gerekmez.

Birleştirme, birden + tipi ve tipi a -> b -> b tip değişkenler yeniden adlandırma tarafından eşit yapılabilir olup olmadığını görmek istiyorum anlamına gelir.

+, Num x => x -> x -> x ürününe sahiptir. Şimdilik sınıf kısıtını göz ardı edelim, ve fonksiyonel tiplerle eşleşip eşleşemeyeceğimizi görelim. Türler x -> x -> x ve a -> b -> b olur. Aslına bakarsanız, gerçekte oldukları gibi, ilişkiselliği kullanmadan: x -> (x -> x) ve a -> (b -> b).

->türünde bir kurucu türüdür. Yani Belirli bir sayı tipini farklı bir türe eşleyen bir işlevdir. Bu durumda -> kurucu, (->) t_1 t_2 işlevsel türüne iki tip t_1 ve t_2 eşleşir (genellikle t_1 -> t_2 ile gösterilir).

Yani tip x -> (x -> x)x ve x ve x uygulanan tür kurucusu -> uygulanan tip yapıcısı -> olan aslında (->) x ((->) x x) olduğunu. Diğer türü (->) a ((->) b b).

Birleştirirken, iki tür için en dıştan tip yapıcıyı düşünün (bu durumda her ikisi için ->). Bu eşleşmezse, birleştiremezsiniz. Aksi halde kurucunun argümanlarını birleştirmeniz gerekir.

yüzden a ile x birleştirmeye gerek. Her ikisi de tür değişkenleridir, bu yüzden yeniden adlandırabiliriz. a'u x ile yeniden adlandırdığımızı varsayalım. Şimdi biz elde, türlerine adlandırma geçerlidir: (->) x ((->) x x) ve (->) x ((->) b b) ve x ve x şimdi maç görüyoruz.

ikinci argüman düşünelim. Bu bir tür değişkeni değil, bu yüzden tür yapıcıyı eşleştirmek zorundayız ve bu da her ikisi için de ->. Bu yüzden argümanlara tekrar tekrar yolluyoruz.

Biz x ve b eşleştirmek istiyoruz. Her ikisi de tür değişkenleridir, bu yüzden bunlardan birini yeniden adlandırabiliriz. x'u b'a yeniden adlandırdığımızı varsayalım. Bu ikameyi şu türlere uygularız: (->) b ((->) b b) ve (->) b ((->) b b). Şimdi her şey eşleşiyor. Bu nedenle iki tip birleştirir. sınıf kısıtlaması İlişkin

, biz b ile x biz kısıtlaması için ikame uygulanan adlandırmak da öyle Num xNum b oldu ve son iki tip hem Num b => b -> b -> b bulunmaktadır.

Bu size türleri çalışmak ve tipleri nasıl kontrol edilir konusunda bazı anlaşıldığını umuyorum.


Yan not: Bu, tür çıkarımını gerçekleştirirken haskell'in yaptığı şeydir. Öncelikle bilinmeyen bir fonksiyona yeni bir değişken t atar. Daha sonra, onu tanımlayan ifadenin türünü elde etmek için birleştirme kullanır ve t ile hangi türün ilişkilendirildiğini kontrol eder ve bu, işlevin türüdür.

+0

Sanırım bu, tip kurucularla biraz fazla mekanikleşiyor. Kavramsal bir örnek (yani, neyle birleştiğini), birleşme sürecinin nasıl işlediğine dair örneklemden önce sahip olmak için yararlı olacaktır. – Cubic

İlgili konular