Uygulama sitesinde aynı görünüyorlar ama elbette farklılar. Bu iki işlevden birini map
veya fmap
bir 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 a
değ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 ( a
ve b
yukarıdaki tanımdaki herhangi bir türü ifade etmesine rağmen ), map
iş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 . map
Fonksiyon değerlerinin bir listesi değildir şeye uygulanamadı.
GHC.Base kaynak kodundan okuyabileceğiniz gibi , map
iş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 ) map
liste 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 fmap
ve 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ı Functor
tü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
, Maybe
veri 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 map
fonksiyona bağlıdır.
Sonuç
map
Oysa fonksiyonu (değerlerinin herhangi bir tiptedir) değerlerinin listesi daha fazla bir şey uygulanabilir fmap
fonksiyonu ç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 fmap
hem de aynı sonuçları üretmektedir uygulanabilir map
.
map (+3) [1..5]
fmap (+3) (Just 15)
fmap (+3) (5, 7)