为什么如果我使用“[xs]”,该功能不起作用。而不是“xs”? [英] Why doesn't this function work if I use "[xs]" instead of "xs"?
问题描述
split :: [a] - > Int - > ([a],[a])
split [xs] n =
(取n [xs],drop n [xs])
如果我将变量设为 xs
而不是 [xs]
,签名在两种情况下都是相同的。使用 [xs]
会给出该模式不详尽的错误。测试输入:我知道它告诉我输入的内容不被我的代码覆盖,但不清楚底下发生了什么。
测试输入: [1,2,3] 2
。
不知何故,很多人认为 [xs]
as模式意味着您< xs
来统一列表。但是这是不正确的,因为函数签名(隐式派生或者明确声明)已经会阻止你在你用非列表项调用函数的地方编写代码。
<一个列表有两个构造函数:
[]
;和 h
的$ consc (h:t)
t
tail (包含其余元素的列表)。
然而,Haskell也引入了一些语法糖。例如 [1]
是(1:[])
和 [1 ,4,2]
for (1:(4:(2:[])))
。
这意味着如果你写了 [xs]
,在窗帘后面定义了一个(xs:[])
这意味着你完全匹配所有列表 一个元素,而那个单独的元素(不是整个列表)则是 xs
。
无论如何,解决方案是使用:
分割 xs n =(取n xs ,放下n xs )
既然 take :: Int - > [a] - > [a]
和 drop :: Int - > [a] - > [code> xs
应该是一个列表,Haskell会自动派生出 code> n 应该是 Int
,并且 xs
an [a]
。
请注意,您可以使用 splitAt :: Int - > [a] - > ([a],[a])
。
split = flip splitAt
$ c $>我们可以将签名等同于您的目标。 c>
split :: [a] -> Int -> ([a], [a])
split [xs] n =
(take n [xs], drop n [xs])
The same code works if I give the variable as xs
instead of [xs]
, signatures are same in both cases. Using [xs]
gives the error that pattern is non-exhaustive. I understand it's telling that the input I gave is not covered by my code, but not clear what is happening under the hood.
Test input: [1,2,3] 2
.
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)
withh
the head (first element), andt
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
这篇关于为什么如果我使用“[xs]”,该功能不起作用。而不是“xs”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!