我的理解是,map和fmap的区别在于后者可以返回一个函数吗?Fmap与地图区分的例子?
我正在研究这个http://learnyouahaskell.com的函数部分,有些解释有点不清楚。
地图和FMAP相同的行为在以下几点:
let exMap = map (+1) [1..5]
let exFMap = fmap (+1) [1..5]
什么是FMAP返回功能的一个很好的例子?
我的理解是,map和fmap的区别在于后者可以返回一个函数吗?Fmap与地图区分的例子?
我正在研究这个http://learnyouahaskell.com的函数部分,有些解释有点不清楚。
地图和FMAP相同的行为在以下几点:
let exMap = map (+1) [1..5]
let exFMap = fmap (+1) [1..5]
什么是FMAP返回功能的一个很好的例子?
不,区别在于fmap
适用于任何函子。例如:
readLine :: IO String -- read a line
fmap length readLine :: IO Int -- read a line and count its length
Just 4 :: Maybe Int
fmap (+10) (Just 4) :: Maybe Int -- apply (+10) underneath Just
-- returns (Just 14)
map
变成a -> b
成一个函数[] a -> [] b
(通常写为[a] -> [b]
)。
fmap
变成a -> b
到一个函数f a -> f b
任何函子f
,不仅为f = []
。上面的例子选择f = IO
和f = Maybe
。
这将有助于看看类型签名的每个功能,让我们开始与你正在寻找的map
功能:
map :: (a -> b) -> [a] -> [b]
正如你所看到的,这map
功能列表上运行。然而逻辑上,有许多可以映射的数据结构。这里有一些其他的可能的地图:
map :: (a -> b) -> Map k a -> Map k b
map :: (a -> b) -> Maybe a -> Maybe b
map :: (a -> b) -> IO a -> IO b
这只是冰山一角,许多事情可以被映射!
在不支持类型类的语言中,这可能是您所知道的世界。只有许多功能,您必须使用适当的模块类型对其进行限定,以区分您实际上所指的map
。 Haskell并非如此!
现在让我们来看看fmap
:
fmap :: Functor f => (a -> b) -> f a -> f b
此函数具有完全相同的形式,如上图所示的,但工程上的任何东西这是一个仿函数。
仿函数的定义如下:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
(<$) = fmap . const
希望这使得它显而易见的是一个仿函数是简单地一些支持映射过来。
因此fmap
是通用的,而map
是特定的。
你应该澄清,你不能通过'文本'或'ByteString''fmap',因为它们不是仿函数 – chi
@chi我只是用更好的例子替换它们 – TheInnerLight
@TheInnerLight能给出一个应用这个类型数据的二叉树的例子树a =空|节点a(树a)(树一个)? –
fmap
比map
更普遍 - 事实上对于列表来说没有什么区别 - 在这里你有map == fmap
。
让我们的fmap
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
定义这实际上是说,你可以把一个简单的功能到该容器转换成相同的形状,但不同元素的容器的功能开始。
instance Functor [] where
fmap = map
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just something) = Just (f something)
还有很多,我想几乎使用单一类型的参数,每个集装箱可以是一个仿函数
作为练习,你可以尝试定义一个实例
data Tree a = Tree a [a]
为使用fmap
请参阅@ chi的回答。
请问您是否可以进一步简化并区分函数与应用函数的区别? –
如果你有'a-> b'和'f a',当'f'是一个函子时,你可以用'fmap'来得到'f b'。然而,如果你有'f(a-> b)'和'f a',你不能得到'f b':函数被包装在'f'下面,并且没有办法使它与它的参数交互。应用仿函数定义了一个额外的操作'<*>'允许。 – chi
一个可用的函数是“阅读器”,它确实与函数有关,但现在可能不是最好的阶段了解它 – dfeuer