简体   繁体   中英

Why does feeding init to last not work in Haskell?

So I'm writing a line to get the second to last element of a list. Initially my code was

mySLast x = last.take ((length x) - 1) x

Which worked up until the last function. Realized the my take business is already included in Haskell as init so I rewrote as

mySLast = last.init 

This still doesn't work. I find this puzzling because init::[a]->[a] and last::[a]->a so they definitely should be composable morphisms in the Hask Category.

I tried asking Haskell what it thinks the type is and it said

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]

Even though

ghci> init [3,2,4,1]
[3,2,4]
ghci> last [3,2,4]
4

So I must be misunderstanding something about composing functions in Haskell. Any insight would be greatly appreciated!

Function application binds more tightly than (.) so

last.init [3,2,4,1]

is being parsed as

last . (init [3,2,4,1])

you can use

(last . init) [3,2,4,1]

or

last . init $ [3,2,4,1]

You forgot the $ between init and your list, eg

last . init $ [3,2,4,1]
            ↑ See here 

An alternative solution to this problem that only evaluates the (spine of the) list up to the needed element, rather than using length (which will evaluate the entire spine before walking back to the needed element):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM