为什么在 Haskell 中喂养 init to last 不起作用?
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 中的函数组合有一些误解。任何见解将不胜感激!
您忘记了 init 和列表之间的 $
,例如
last . init $ [3,2,4,1]
↑ See here
函数应用程序绑定比 (.)
更紧密,因此
last.init [3,2,4,1]
被解析为
last . (init [3,2,4,1])
你可以使用
(last . init) [3,2,4,1]
或
last . init $ [3,2,4,1]
这个问题的另一种解决方案是只评估列表的(脊柱)直到所需的元素,而不是使用长度(它将在返回所需元素之前评估整个脊柱):
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
所以我正在写一行来获取列表的倒数第二个元素。最初我的代码是
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 中的函数组合有一些误解。任何见解将不胜感激!
您忘记了 init 和列表之间的 $
,例如
last . init $ [3,2,4,1]
↑ See here
函数应用程序绑定比 (.)
更紧密,因此
last.init [3,2,4,1]
被解析为
last . (init [3,2,4,1])
你可以使用
(last . init) [3,2,4,1]
或
last . init $ [3,2,4,1]
这个问题的另一种解决方案是只评估列表的(脊柱)直到所需的元素,而不是使用长度(它将在返回所需元素之前评估整个脊柱):
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