我是Haskell的新手,我认为在Haskell中的函数map map和map.map是相同的。我的终端有两种不同的类型,
(map.map) :: (a -> b) -> [[a]] -> [[b]]和
(map map) :: [a -> b] -> [[a] -> [b]]这些函数在语法方面有何不同,每个函数的确切含义是什么?
发布于 2019-08-12 18:00:18
map map表达式将使用第二个map作为第一个表达式的参数。这意味着如果我们派生类型,我们会看到:
map :: ( a -> b ) -> ([a] -> [b])
map :: (c -> d) -> ([c] -> [d])
-----------------------------------------------
a ~ (c -> d), b ~ [c] -> [d]因此,这意味着a具有与c -> d相同的类型,而b具有与[c] -> [d]相同的类型。因此,这意味着map map的类型是:
map map :: [a] -> [b]
:: [c -> d] -> [[c] -> [d]]因此,在这里,map map将c -> d类型的函数列表作为参数,它将生成一个函数列表,该列表执行与这些函数的映射。
因此,这意味着如果你写:
(map map) [(+1), (*2), (-3)]您可以检索类似如下的内容:
[map (+1), map (*2), map (-3)]但对于map . map来说,情况并非如此。此表达式等同于(.) map map。函数接受两个函数f和g,并将它们组合为\x -> f (g x)。因此,该类型意味着:
(.) :: ( b -> c ) -> (( a -> b ) -> (a -> c))
map :: (d -> e) -> ([d] -> [e])
map :: (f -> g) -> ([f] -> [g])
-------------------------------------------------------------------------
b ~ d -> e ~ [f] -> [g], c ~ [d] -> [e], a ~ f -> g, d ~ f, e ~ g(.) map map的类型如下:
(.) map map :: a -> c
:: (f -> g) -> ([d] -> [e])
:: (f -> g) -> ([[f]] -> [[g]])此函数接受f -> g类型的单个函数,并将生成一个接受f列表的函数,它可以将这些列表映射到gs。
因此,(map . map) (+1)将生成一个函数,以便:
(map . map) (+1) [[1,4,2,5],[1,3,0,2]]它将生成:
[[2,5,3,6], [2,4,1,3]]发布于 2019-08-12 18:01:39
map . map ≡ (\x -> map (map x))
≡ (\x y -> map (map x) y)
map map ≡ map (map)
≡ (\x -> map map x)因此,基本上,.在外部map的“函数括号”中隐藏了一个额外的变量。
它将map (map) x转换为map (map x)。正如类型所展示的那样,两者的含义完全不同。
在map (map x) y中,x是一个将应用于嵌套列表y内部元素的函数,因为map x (部分应用程序)是一个列表映射函数。而在map map x中,高阶函数map本身被映射到列表上。这听起来很奇怪,但这是可能的,它只需要一个函数列表(这将是内部map映射的函数),并生成另一个函数列表(每个函数都在一个特定的内部列表上进行映射)。
https://stackoverflow.com/questions/57458890
复制相似问题