Uygulama sitesinde aynı görünüyorlar ama elbette farklılar. Bu iki işlevden birini mapveya fmapbir değerler listesine uyguladığınızda , aynı sonucu üretirler ancak bu, aynı amaç için tasarlandıkları anlamına gelmez.
Bu iki işlev hakkında bilgi sorgulamak için bir GHCI oturumu (Glasgow Haskell Compiler Interactive) çalıştırın, ardından uygulamalarına bir göz atın ve birçok farkı keşfedeceksiniz.
harita
GHCI sorgusu hakkında bilgi için map
Prelude> :info map
map :: (a -> b) -> [a] -> [b]
ve herhangi bir türden adeğerlerin bir listesini veren herhangi bir türden değer listesine uygulanabilen yüksek dereceli bir işlev olarak tanımlandığını göreceksiniz b. Polimorfik ( ave byukarıdaki tanımdaki herhangi bir türü ifade etmesine rağmen ), mapişlevin Haskell'deki diğer birçok veri türü arasında yalnızca bir olası veri türü olan bir değerler listesine uygulanması amaçlanmıştır . mapFonksiyon değerlerinin bir listesi değildir şeye uygulanamadı.
GHC.Base kaynak kodundan okuyabileceğiniz gibi , mapişlev aşağıdaki gibi uygulanır
map _ [] = []
map f (x:xs) = f x : map f xs
bu , listenin başını ( x) kuyruğundan (the xs) dışarı çekmek için desen eşleştirmeden yararlanır , ardından :(eksileri) değer oluşturucusunu kullanarak yeni bir liste oluşturur f x( "f, x'e uygulandı" olarak okuyun ) mapliste boşalana kadar üst üste yineleme . mapİşlevin uygulanmasının başka herhangi bir işleve değil, yalnızca kendisine bağlı olduğunu belirtmek gerekir.
fmap
Şimdi hakkında bilgi için sorgulamaya çalışın fmapve oldukça farklı bir şey göreceksiniz.
Prelude> :info fmap
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
...
Bu zaman fmap, uygulamaları Functortür sınıfına ait olmak isteyen veri türleri tarafından sağlanması gereken işlevlerden biri olarak tanımlanır . Bu , işlev için bir uygulama sağlayabilen yalnızca "değerler listesi" veri türü değil, birden fazla veri türü olabileceği anlamına gelir fmap. Bu, fmapçok daha geniş bir veri türü kümesine uygulanabilir: gerçekten de işlevciler!
GHC.Base kaynak kodundan okuyabileceğiniz gibi, işlevin olası bir uygulaması fmap, Maybeveri türü tarafından sağlanandır :
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
ve bir başka olası uygulama, 2 tuple veri türü tarafından sağlanan olandır
instance Functor ((,) a) where
fmap f (x,y) = (x, f y)
ve başka bir olası uygulama, liste veri türü tarafından sağlanan uygulamadır (tabii ki!):
instance Functor [] where
fmap f xs = map f xs
hangi mapfonksiyona bağlıdır.
Sonuç
mapOysa fonksiyonu (değerlerinin herhangi bir tiptedir) değerlerinin listesi daha fazla bir şey uygulanabilir fmapfonksiyonu çok daha fazla veri türleri uygulanabilir: funktoru sınıfına ait olanlar (örneğin Belkiler, küpe, listeler, vb her ). Yana "değerler listesi" o (bunun için bir uygulama sağlar, çünkü) veri türü bir funktor da fmaphem de aynı sonuçları üretmektedir uygulanabilir map.
map (+3) [1..5]
fmap (+3) (Just 15)
fmap (+3) (5, 7)