Haskell Map函数将非函数作为第一个参数
这是从O'reilly-Haskell的书中摘录的代码 样本运行方式:Haskell Map函数将非函数作为第一个参数,haskell,Haskell,这是从O'reilly-Haskell的书中摘录的代码 样本运行方式: -- file: ch19/divby1.hs divBy :: Integral a => a -> [a] -> [a] divBy numerator = map (numerator `div`) 让我困惑的是 为什么表达式中的LHSdivBy和momerator上有两个变量: ghci> divBy 50 [1,2,5,8,10] [50,25,10,6,5] 变量除以和分子在末尾分配
-- file: ch19/divby1.hs
divBy :: Integral a => a -> [a] -> [a]
divBy numerator = map (numerator `div`)
让我困惑的是
divBy
和momerator
上有两个变量:
ghci> divBy 50 [1,2,5,8,10]
[50,25,10,6,5]
除以
和分子
在末尾分配了哪些值
map
功能类型为
map::(a->b)->[a]->[b]
。
在上面的表达式中,参数分子
不是函数类型,并且
div
不是数组类型。但是代码正在运行李>
我在这里遗漏了什么?关于eta转换和签名
首先,我想你错过了一些`
:在分子div`
中(是的,我想你吃了它们-你必须输入这个作为``分子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
这里可能更清楚的是,分子
是第一个参数(类型为a
),而ns
是第二个参数(类型为[a]
),而divBy
当然是函数的名称
这是因为有一个名为的东西,基本上说你可以把\x->fx
缩短为f
——但有时要注意,它通常用于编写Haskell代码
你的问题
让我困惑的是
为什么表达式中的LHS divBy和momerator上有两个变量:
ghci> divBy 50 [1,2,5,8,10]
[50,25,10,6,5]
答案:这些不是变量-第一个是您在此行中声明的函数的名称,第二个是它的第一个参数的名称
您可能想知道第二个函数去了哪里(见上文)-简短的回答是:divBy
实际上是一个函数,它接受一个a
并返回另一个函数[a]->[a]
,因此,只要返回一个函数,实际上您只需要给出一个参数(确实如此)
最后分配了哪些值、变量除数和分子
答案:正如我所说的,divBy
是函数的名称-分子
将得到第一个参数
divBy numerator = map (numerator `div`)
分子
是5
map函数类型是map::(a->b)->[a]->[b]
在上面的表达式中,参数分子
不是函数类型,div
不是数组类型。但是代码正在运行
我错过了什么
基本上你缺少了括号-(分子'div`)
是一个所谓的函数-\n->分子'div`n
-把它想象成中缀的第二个参数有一个洞:(免责声明:伪代码)(分子'div`
)
所以(分子'div')
实际上是一个函数积分a=>a->a
,因此它适合映射的第一个参数
第二个在哪里?同样,这与上面的故事是一样的:map(分子'div')
是一个函数积分a=>[a]->[a]
,这就是您声明的右侧所缺少的除以分子
我希望你能用我在第一部分给你的答案来理解
如果您有问题,请留下评论-我将尝试在需要的地方添加解释。我会像这样阅读此代码:
divBy
的类型表示它需要两个参数[1],一个a
和一个[a]
,但其声明的LHS只显示一个参数,即分子
。让我自己加上第二个论点,来完成这幅图:
divBy分子xs=map(分子'div`)xs
注意,我使用了名称xs
(在“多个x”中读作x-es),因为第二个参数是一个列表。我本可以使用,比如说x
,但是使用xs
是一个直观的提醒,它是一个列表,在以后避免混淆方面有很大帮助
现在情况看起来更清楚了:
说divBy分子xs
与说map(分子'div`)xs
完全相同:无论我在哪里看到前一个表达式,我都可以用后一个表达式替换它
map(分子'div')xs在我看来相当不错:map
的第二个参数是xs
,它应该是一个列表。map
,(分子'div')
的第一个参数需要是a->a
类型的函数,其中a
是整数的一个实例。也就是说,(分子'div')::积分a=>a->a
必须保持不变。所以现在我只需要关心为什么会这样
我试图弄明白为什么(分子'div')
的类型是积分a=>a->a
。其他答案解释了为什么会这样,我很高兴李>
[1] 为了学究气,divBy
只接受一个论点等,但我现在是一个教育学者 我想,你错过了地图中div周围的符号(分子div)是的,这是stack.overflow效应。。让我纠正一下。。。
divBy numerator = map (numerator `div`)
λ> divBy 5 [1..10]
[5,2,1,1,1,0,0,0,0,0]