-- file: ch19/divby1.hs
divBy :: Integral a => a -> [a] -> [a]
divBy numerator = map (numerator `div`)
这是O' reilly - Haskell书中的代码摘录。
示例运行为,
ghci> divBy 50 [1,2,5,8,10]
[50,25,10,6,5]
令我困惑的是
为什么表达式中LHS divBy
和numerator
有两个变量:
divBy numerator = map (numerator `div`)
最后分配的变量divBy
和numerator
是什么值?
map
函数类型是
map :: (a -> b) -> [a] -> [b]
。
在上面的表达式中,参数numerator
不是函数类型,而且
div
不是数组类型。但是代码正在运行!! 我在这里缺少什么?
答案 0 :(得分:4)
首先我想你错过了一些`
:在numerator `div`
中(是的,我认为这样做了 - 你必须输入`` numerator `div` ``
来工作!)
此:
divBy :: Integral a => a -> [a] -> [a]
divBy numerator = map (numerator `div`)
是另一种写作方式
divBy :: Integral a => a -> [a] -> [a]
divBy = \ numerator -> map (numerator `div`)
可以扩展到
divBy :: Integral a => a -> [a] -> [a]
divBy = \ numerator ns -> map (numerator `div`) ns
如果你愿意,可以将参数放回左边:
divBy :: Integral a => a -> [a] -> [a]
divBy numerator ns -> map (numerator `div`) ns
这里可能更清楚的是numerator
是第一个参数(类型为a
)而ns
是第二个([a]
类型)而divBy
1}}当然是函数的名称。
这是有效的,因为有一些名为eta conversion的内容基本上表示您可以将\x -> f x
简化为f
- 但有时候要注意run into trouble这个但是它&# 39;经常用于编写point-free-style Haskell代码。
令我困惑的是
为什么表达式中的LHS divBy和numerator有两个变量:
divBy numerator = map (numerator `div`)
答案:那些不是变量 - 第一个是您在此行中声明的函数的名称,第二个是它的名称' s第一个论点。
你可能想知道第二个去哪了(见上文) - 简短的回答是:divBy
实际上是一个函数,它接受a
并返回另一个函数[a] -> [a]
所以那里只要你返回一个函数(并且你做),你实际上只有一个参数。
什么值,最后分配变量divBy和numerator?
回答:正如我所说divBy
是你的函数的名称 - numerator
将获得第一个参数,所以
λ> divBy 5 [1..10]
[5,2,1,1,1,0,0,0,0,0]
numerator
是5
map函数类型为
map :: (a -> b) -> [a] -> [b]
在上面的表达式中,参数numerator
不是函数类型,div
不是数组类型。但是代码正在运行!!我在这里缺少什么?
基本上你错过了括号 - (numerator `div`)
是一个所谓的section - 它实际上是函数\n -> numerator `div` n
- 认为它有一个洞在 infix `div`
的第二个参数:(免责声明:伪代码)(numerator `div` _)
。
所以(numerator `div`)
实际上是一个函数Integral a => a -> a
,所以它适合map
的第一个参数。
现在第二个在哪里?再说一遍,就像上面一样:map (numerator `div`)
是一个函数Integral a => [a] -> [a]
,这就是你的声明divBy numerator
右边缺少的东西。
我希望你能在这个答案的第一部分找到我给你的东西。
如果您有疑问,请发表评论 - 我会尝试在需要时添加解释。
答案 1 :(得分:1)
我会像这样阅读这段代码:
divBy
的类型表示它需要两个参数[1],a
和[a]
,但其声明的LHS只显示一个参数,即{{1 }}。所以,让我自己添加第二个参数,以完成图片:
numerator
请注意,我使用名称divBy numerator xs = map (numerator `div`) xs
(读作x-es,因为"多个x"),因为第二个参数是一个列表。我可以使用,比如说xs
,但是使用x
是一个视觉提示,即事物是一个列表,它可以帮助我避免混淆。
现在情况看起来更清楚了:
xs
与说divBy numerator xs
完全一样:无论我在哪里看到前一个表达式,我都可以用后一个表达式替换它。map (numerator `div`) xs
看起来相当不错:map (numerator `div`) xs
的第二个参数map
绝对是一个列表,应该是它。 xs
的第一个参数map
需要是(numerator `div`)
类型的函数,其中a -> a
是a
的实例类型。也就是说,Integral
必须成立。所以现在我只需要关注为什么会出现这种情况。(numerator `div`) :: Integral a => a -> a
为什么类型(numerator `div`)
。其他答案已经解释了为什么会这样,我很高兴! [1]要迂腐,Integral a => a -> a
只接受一个论点等,但我现在正在教育学。