[英]Why does feeding init to last not work in Haskell?
因此,我正在写一行以获取列表的倒数第二个元素。 最初我的代码是
mySLast x = last.take ((length x) - 1) x
直到last
功能。 实现了我的take
业务已经包含在Haskell作为init
,所以我改写为
mySLast = last.init
这仍然行不通。 我感到困惑的是因为init::[a]->[a]
和last::[a]->a
所以它们在Hask类别中绝对应该是可组合的词素 。
我试图问Haskell,它认为类型是什么,它说
ghci> :t last.init
last.init :: [c] -> c
ghci> last.init [3,2,4,1]
<interactive>:45:6:
Couldn't match expected type ‘a -> [c]’
with actual type ‘[Integer]’
Relevant bindings include
it :: a -> c (bound at <interactive>:45:1)
Possible cause: ‘init’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘init [3, 2, 4, 1]’
In the expression: last . init [3, 2, 4, 1]
即使
ghci> init [3,2,4,1]
[3,2,4]
ghci> last [3,2,4]
4
因此,我一定会误解有关在Haskell中编写函数的知识。 任何见解将不胜感激!
函数应用程序比(.)
绑定更紧密
last.init [3,2,4,1]
被解析为
last . (init [3,2,4,1])
您可以使用
(last . init) [3,2,4,1]
要么
last . init $ [3,2,4,1]
您忘记了init和列表之间的$
,例如
last . init $ [3,2,4,1]
↑ See here
此问题的另一种解决方案是,仅评估列表的(书脊)直至所需元素,而不使用长度(在返回所需元素之前将评估整个书脊):
takeTail n xs = go (drop n xs) xs
where
go (_:ys) (_:xs) = go ys xs
go [] xs = xs -- Stop and return xs when ys runs out
> head . takeTail 2 $ [1,2,3,4]
3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.