split :: [a] -> Int -> ([a], [a])
split [xs] n =
(take n [xs], drop n [xs])
Run Code Online (Sandbox Code Playgroud)
如果我将变量xs改为代替,则相同的代码可以工作[xs],签名在两种情况下都相同.使用[xs]给出了模式非穷举的错误.我理解这说明我提供的输入不在我的代码中,但不清楚幕后发生了什么.
测试输入:[1,2,3] 2.
Wil*_*sem 11
不知何故,很多人都认为[xs]模式意味着你统一了一个列表xs.但这是不正确的,因为函数签名(隐式派生或明确声明)已经阻止您编写使用非列表项调用函数的代码.
列表有两个构造函数:
[]; 和(h : t)与h所述头部(第一元件),并且t所述尾部(与其余元素的列表).然而,Haskell也引入了一些语法糖.例如[1],简称(1:[])和[1, 4, 2]for (1:(4:(2:[]))).
因此,这意味着,如果你写的[xs],窗帘后面你定义的模式(xs: [])这从而意味着你匹配所有名单正好一个元素,而单元素(而不是整个列表)然后xs.
无论如何,解决方案是使用:
split xs n = (take n xs, drop n xs)Run Code Online (Sandbox Code Playgroud)
由于这两个take :: Int -> [a] -> [a]和drop :: Int -> [a] -> [a]在该签名有xs应该是一个列表,哈斯克尔会自动推导n应该是一个Int,和xs一个[a].
请注意,您也可以使用splitAt :: Int -> [a] -> ([a], [a]).我们可以使签名等同于您所定位的签名:
split = flip splitAt
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
207 次 |
| 最近记录: |