为什么如果我使用“[xs]”,该功能不起作用。而不是“xs”? [英] Why doesn't this function work if I use "[xs]" instead of "xs"?

查看:120
本文介绍了为什么如果我使用“[xs]”,该功能不起作用。而不是“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)
  • head (第一个元素)和 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>


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) 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

这篇关于为什么如果我使用“[xs]”,该功能不起作用。而不是“xs”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆