Haskell 为什么不是';是否需要在此函数中提供参数?
我是Haskell的新手,本周我在几张幻灯片中发现了这个特殊的功能。我试图理解为什么以下函数不需要包含参数:Haskell 为什么不是';是否需要在此函数中提供参数?,haskell,pointfree,Haskell,Pointfree,我是Haskell的新手,本周我在几张幻灯片中发现了这个特殊的功能。我试图理解为什么以下函数不需要包含参数: -- Return all final segments of the argument, longest first -- (horrible runtime complexity, used here for illustration purposes only) tails :: [a] -> [[a]] tails = reverse . map reverse . in
-- Return all final segments of the argument, longest first
-- (horrible runtime complexity, used here for illustration purposes only)
tails :: [a] -> [[a]]
tails = reverse . map reverse . inits . reverse
如果我像
tails“thisisastring”
那样调用它,那么这将是一个有效的参数。是否需要提供一个参数,例如tails xs=…
。我以前看到的所有其他函数都是这样的。参数是隐式的。或者换一种说法,相反。地图倒过来。初始化。反向
计算为类型为[a]->[[a]]]
的函数
考虑一个更简单的例子:
double_impl x = x * 2
double = double_impl
此处的double
的类型与double\u impl
的类型相同,即它采用一个参数typeclassNum
:
main = do
print $ double_impl 5
print $ double 5
-- Out: 10
-- Out: 10
该参数是隐式的。或者换一种说法,
相反。地图倒过来。初始化。反向
计算为类型为[a]->[[a]]]
的函数
考虑一个更简单的例子:
double_impl x = x * 2
double = double_impl
此处的double
的类型与double\u impl
的类型相同,即它采用一个参数typeclassNum
:
main = do
print $ double_impl 5
print $ double 5
-- Out: 10
-- Out: 10
通过检查
tails
的类型,我们可以看到它是一个函数
为了计算它的类型,我们首先写下组合中所有中间函数的类型。请注意,我们对函数的每次出现都使用新的类型变量
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]
现在我们有了map reverse
has type[[e]]->[[e]]]
,因为我们通过比较表达式得到了一些类型e
的c=d=[e]
reverse :: c -> d -- for some c and d
reverse :: [e] -> [e] -- for some e
因此,最后两种中间体具有不同的类型
map reverse :: [[e]] -> [[e]]
reverse :: [f] -> [f]
现在我们开始尝试匹配类型。首先我要强调的是,这些显然不是真正的类型!(很抱歉所有的帽子,但我不想让任何人错过。)
下一篇作文:
map reverse . inits . reverse :: [a] -*- [[a]] = [[e]] -*> [[e]]
-- again, we have [[a]] = [[e]], so e = a, and we have
map reverse . inits . reverse :: [a] -> [[a]]
最后,我们有
reverse . map reverse . inits . reverse :: [a] -*- [[a]] = [f] -*> [f]
-- This time we have [[a]] = [f], so we must have f = [a], so the type
-- of the final composition is
tails = reverse . map reverse . inits . reverse :: [a] -> [[a]]
由于
tails
的类型为[a]->[[a]]
,因此它必须是一个函数,它接受a
s列表作为参数,并返回a
s列表。通过检查其类型,我们可以看出tails
是一个函数
为了计算它的类型,我们首先写下组合中所有中间函数的类型。请注意,我们对函数的每次出现都使用新的类型变量
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]
现在我们有了map reverse
has type[[e]]->[[e]]]
,因为我们通过比较表达式得到了一些类型e
的c=d=[e]
reverse :: c -> d -- for some c and d
reverse :: [e] -> [e] -- for some e
因此,最后两种中间体具有不同的类型
map reverse :: [[e]] -> [[e]]
reverse :: [f] -> [f]
现在我们开始尝试匹配类型。首先我要强调的是,这些显然不是真正的类型!(很抱歉所有的帽子,但我不想让任何人错过。)
下一篇作文:
map reverse . inits . reverse :: [a] -*- [[a]] = [[e]] -*> [[e]]
-- again, we have [[a]] = [[e]], so e = a, and we have
map reverse . inits . reverse :: [a] -> [[a]]
最后,我们有
reverse . map reverse . inits . reverse :: [a] -*- [[a]] = [f] -*> [f]
-- This time we have [[a]] = [f], so we must have f = [a], so the type
-- of the final composition is
tails = reverse . map reverse . inits . reverse :: [a] -> [[a]]
由于
tails
的类型为[a]->[[a]]
,因此它必须是一个函数,接受a
s列表作为参数,并返回a
s列表。这称为无点样式(其中“点”是一个数学术语,在这里基本上表示“参数”)
即使是tails xs=…
也只是tails=\xs->…
的语法糖,所以你需要做的就是让自己相信tails
是一个函数
reverse
、map reverse
和inits
都是功能:
是一个高阶函数;它将一个函数作为参数,并返回另一个函数map
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]
map reverse
是一个函数,因为map
应用于函数reverse
是一项功能相反。地图反转
- 所以<代码>相反。地图倒过来。inits是一个函数
- 和
是一项功能相反。地图倒过来。初始化。反转
因为
tails
被分配了reverse的值。地图倒过来。初始化。反向
,尾部
本身也是一个函数。这称为无点样式(其中“点”是一个数学术语,这里基本上表示“参数”)
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]
即使是tails xs=…
也只是tails=\xs->…
的语法糖,所以你需要做的就是让自己相信tails
是一个函数
reverse
、map reverse
和inits
都是功能:
是一个高阶函数;它将一个函数作为参数,并返回另一个函数map
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]
map reverse
是一个函数,因为map
应用于函数reverse
是一项功能相反。地图反转
- 所以<代码>相反。地图倒过来。inits是一个函数
- 和
是一项功能相反。地图倒过来。初始化。反转
因为
tails
被分配了reverse的值。地图倒过来。初始化。反向
,尾部
本身也是一种功能。我开始有点理解了。我试图确定为什么尾部会导致[a]->[a]]。从reverse开始(在末尾,因为),它需要[a]->[a],然后inits需要[a]->[a]],这是有效的,因为reverse的输出是[a]。在那之后,我被卡住了,因为map需要一个函数(再次反转),但也需要[a]w
reverse :: [a] -> [a]
inits :: [b] -> [[b]]
map :: (c -> d) -> [c] -> [d]