Int -> ([a], [a]) split [xs] n = (take n [xs], drop n [xs]) 如果我将变量指定为 xs 而不是 [xs-6ren">
gpt4 book ai didi

haskell - 如果我使用 "[xs]"而不是 "xs"为什么这个函数不起作用?

转载 作者:行者123 更新时间:2023-12-02 05:47:34 28 4
gpt4 key购买 nike

split :: [a] -> Int -> ([a], [a])
split [xs] n =
(take n [xs], drop n [xs])

如果我将变量指定为 xs 而不是 [xs],则相同的代码有效,两种情况下的签名相同。使用 [xs] 会给出模式不详尽的错误。我知道这表明我提供的输入未包含在我的代码中,但不清楚幕后发生了什么。

测试输入:[1,2,3] 2

最佳答案

不知何故,很多人认为 [xs] 作为模式意味着您统一一个列表与 xs。但这是不正确的,因为函数签名(隐式派生或显式声明)已经会阻止您在使用非列表项调用函数的地方编写代码。

一个列表有两个构造函数:

  • 空列表[];和
  • (h : t) h head(第一个元素)和 t > tail(包含剩余元素的列表)。

然而,Haskell 也引入了一些语法糖。例如 [1](1:[]) 的缩写,[1, 4, 2](1 :(4:(2:[])))

所以这意味着如果你写[xs],你在幕后定义了一个模式(xs: []),这意味着你用<匹配所有列表em>恰好一个元素,然后那个元素(不是整个列表)就是xs

无论如何,解决方案是使用:

split <b>xs</b> n = (take n <b>xs</b>, drop n <b>xs</b>)

由于两者 take :: Int -> [a] -> [a]drop :: Int -> [a] -> [a]在签名中 xs 应该是一个列表,Haskell 会自动推导出 n 应该是一个 Int,并且 xs 一个 [a]

请注意,您可以使用 splitAt :: Int -> [a] -> ([a], [a])以及。我们可以使签名等同于您使用的目标签名:

split = flip splitAt

关于haskell - 如果我使用 "[xs]"而不是 "xs"为什么这个函数不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48884276/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com