您好我有一个简单的haskell定义的查询。我有一个定义,但我不完全理解它。
该函数接受函数列表和项目,并返回通过应用该函数形成的列表。
applyAll = \fs -> \x -> map(\n -> n x) fs
有人可以解释一下n的作用以及为什么fs在地图之外的功能?
答案 0 :(得分:8)
间距会误导你。看起来map(\n -> n x)
是函数调用,但这里的括号用于分组,而不是函数调用。 map
有两个论点;完整调用是map (\n -> n x) fs
,其中(\n -> n x)
是第一个参数(lambda表达式),fs
是第二个。
lambda \n -> n x
是一个函数,它将函数作为参数,并返回将该函数应用于x
的结果。 n
就是这里的论点。 \n -> n x
的类型为(a -> b) -> b
(其中a
是x
的类型)。如果您已经了解了部分,则lambda等同于($ x)
部分。如果还没有,请忽略最后一句话。
答案 1 :(得分:2)
功能定义:
applyAll = \fs -> \x -> map(\n -> n x) fs
与:
相同applyAll fs x = map(\n -> n x) fs
现在你可能会问,“如果->
只是我的函数applyAll
的参数,那么applyAll
做什么.Haskell没有多参数函数的概念。你看到多个参数函数只是链接在一起的许多函数每个带有单个参数。在(applyAll fs) -> x = map (\n -> n x) fs
的情况下,它只是两个链接在一起的函数:
applyAll fs
x
是一个与另一个标识为map
的参数相关联的函数,用于生成Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs
<interactive>:1:10: Not in scope: `xs'
Prelude> let xs = [1..5]
-- hah, BOOM! I told you haskell's strongly typed...
Prelude> :t applyAll xs
<interactive>:1:10:
Couldn't match expected type `t0 -> b0' with actual type `Integer'
Expected type: [t0 -> b0]
Actual type: [Integer]
In the first argument of `applyAll', namely `xs'
In the expression: applyAll xs
Prelude> let xs = [(1 +), (2 +), (3 *), (4 /)]
Prelude> :t xs
xs :: [Double -> Double]
Prelude> :t applyAll xs
applyAll xs :: Double -> [Double]
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs 3
applyAll xs 3 :: [Double]
Prelude> applyAll xs 3
[4.0,5.0,9.0,1.3333333333333333]
返回的值列表。
我可以在ghci中试试这个:
map
map :: (a -> b) -> [a] -> [b]
的类型是什么?
map
这告诉我f
接受一个函数 - 让它调用它f
和一个值列表来返回另一个值列表。函数a
是一个类型b
的值,返回另一个map
类型的值。因此f
继续将[a]
应用于列表b
中的每个值,以返回另一个填充了applyAll
类型值的列表。
在f
中,函数\n -> n x
为n
。这是一个lambda表达式(您可以称之为匿名函数),它使用x
标识的值并将[a]
应用于它。这将继续在类型定义中由[b]
标识的输入列表中的每个项目,直到它用完为在类型定义中生成由{{1}}标识的另一个列表。
答案 2 :(得分:0)
这是一个简单的函数定义:
f x = 2*x + 1
这将创建一个新函数f
,它接受一个参数。您可以稍后使用它:
main = print (f 3)
...将打印7.有时,定义函数而不给它命名是很方便的。其语法为\{- argument -} -> {- function body -}
;例如,我们可以通过以下方式执行f
的匿名版本:
main = print ((\x -> 2*x + 1) 3)
现在,您对applyAll
的定义只是这样做了好几次。如果我们想要,我们可以在where
子句中明确命名所有内容:
applyAll = outerMost where
outerMost fs = mapApply where
mapApply x = map applyToX fs where
applyToX n = n x
......虽然我认为你会同意额外的冗长不会让事情变得更清楚!远离匿名函数的更自然(但不那么机械)的翻译将如下所示:
applyAll fs x = map applyToX fs where
applyToX n = n x
现在希望这几乎可以像英语一样阅读:将所有函数fs
应用于单个值x
,我们映射“应用单个函数的函数(我们暂时命名为{ {1}})在所有函数列表中的值n
“。