Somehow a lot of people think that [xs]
as pattern means that you unify a list with xs
. But this is incorrect, since the function signature (either derived implicitly, or stated explicitly) already will prevent you to write code where you call the function with a non-list item.
A list has two constructors:
- the empty list
[]
; and
- the "cons"
(h : t)
with h
the head (first element), and t
the tail (a list with the remaining elements).
Haskell however introduces some syntactical sugar as well. For example [1]
is short for (1:[])
, and [1, 4, 2]
for (1:(4:(2:[])))
.
So that means that if you write [xs]
, behind the curtains you defined a pattern (xs: [])
which thus means you match all lists with exactly one element, and that single element (not the entire list) is then xs
.
Anyway, the solution is to use:
split xs n = (take n xs, drop n xs)
Since both take :: Int -> [a] -> [a]
and drop :: Int -> [a] -> [a]
have in the signature that xs
is supposed to be a list, Haskell will derive automatically that n
is supposed to be an Int
, and xs
an [a]
.
Note that you can use splitAt :: Int -> [a] -> ([a], [a])
as well. We can make the signature equivalent to the one you target with:
split = flip splitAt
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…