我仍然是Haskell的初学者。我能在Haskell中进行双重映射吗?
例如,如果我有一个[[Char]]
,我想将每个[Char]
中的每个Char
转换为小写,是否有一种简单的方法可以做到这一点,而不是像下面这样:
exampleF [] = []
exampleF (x:xs) = (map toLower x) : exampleF xs
我仍然是Haskell的初学者。我能在Haskell中进行双重映射吗?
例如,如果我有一个[[Char]]
,我想将每个[Char]
中的每个Char
转换为小写,是否有一种简单的方法可以做到这一点,而不是像下面这样:
exampleF [] = []
exampleF (x:xs) = (map toLower x) : exampleF xs
事实上,这里有一个很好的模式:
map :: (a -> b) -> [a] -> [b]
(map.map) :: (a -> b) -> [[a]] -> [[b]]
(map.map.map) :: (a -> b) -> [[[a]]] -> [[[b]]]
等等,诸如此类
(fmap . fmap) :: (Functor m, Functor n) => ( a -> b ) -> m (n a) -> m (n b)
- Alexey Birukov你可以将 map f
看作是将一个函数 f :: a -> b
转换成列表上的函数 map f :: [a] -> [b]
,所以如果你想将其进一步转换为列表的列表上的函数,则只需要再次使用 map
即可得到 map (map f) :: [[a]] -> [[b]]
。
在这个特定的例子中,变成了:
exampleF = map (map toLower)
exampleF xss = map (\xs -> map toLower xs) xss
的另一种写法是 exampleF xss = map (map toLower) xss
。不过,我们鼓励使用 hammar 写的方式(因为它是 eta-reduced 和 point-free 的)。如果您还没有习惯这种写法,那么您会逐渐习惯的。 - Dan Burton