haskell让我混合各种类型的列表吗?
所以我被告知名单有两种形式:haskell让我混合各种类型的列表吗?,haskell,Haskell,所以我被告知名单有两种形式: (a:as),其中a是头,as是尾 [a],其中a是列表 我这里的问题是,如果我正在处理的函数invertor::[a]->[a] 定义函数时是否可以使用类型(a:as) 比如说 inverte::[a]->[a] inverte [] =[] inverte (a:as) = (as:a) 这将失败。为了清晰起见,我将使用不同的变量名重写最后一行: inverte (x:xs) = (xs:x) 变量x的类型为a,但变量xs的类型为[a](即a的列表)。
(a:as)
,其中a
是头,as
是尾[a]
,其中a
是列表invertor::[a]->[a]
定义函数时是否可以使用类型(a:as)
比如说
inverte::[a]->[a]
inverte [] =[]
inverte (a:as) = (as:a)
这将失败。为了清晰起见,我将使用不同的变量名重写最后一行:
inverte (x:xs) = (xs:x)
变量x
的类型为a
,但变量xs
的类型为[a]
(即a
的列表)。:
运算符要求其第一个参数为元素,第二个参数为同一类型的列表。因此,交换它们将不起作用
一个合法(但缓慢)的方法是说
xs++[x]
。您可能还想看看。这将失败。为了清晰起见,我将使用不同的变量名重写最后一行:
inverte (x:xs) = (xs:x)
变量x
的类型为a
,但变量xs
的类型为[a]
(即a
的列表)。:
运算符要求其第一个参数为元素,第二个参数为同一类型的列表。因此,交换它们将不起作用
一种合法(但速度较慢)的方法是说
xs++[x]
。您可能还想看看。不,编译器会告诉您这是不可能的
您混淆了列表的两种不同“视图”。为了明确我所说的内容,让我们定义一个不同的列表实现
data List a = Cons a (List a) | EmptyList
mylist :: List Char
mylist = Cons 'a' (Cons 'h' (Cons 'a' (Cons '!' EmptyList)))
oldlist :: [Char]
oldlist = 'a' : ('h' : ('a' : ('!' : [])))
-- or
oldlist = ['a','h','a','!']
-- alternatively you could write this as
oldlist = "aha!"
-- because `String` is just a list of `Char`.
在左侧,您可以编写您定义的新数据类型,在右侧,您可以提供所有运算符来构造此类类型或在函数定义中进行模式匹配
现在回到haskell内置列表类型——为了让事情变得更加明显,我将称之为“值级别”——变量x
,类型变量a
和(x:xs)
是列表中要匹配的两种模式,如下所示[]
对应于(x:xs)
,并且Cons x xs
至[]
空列表
是这些表达式的类型,对应于列表a
[a]
现在,当您尝试构建函数时,我们必须仔细查看
(x:xs)
,并检查模式匹配组件的类型以及该行的右侧
x :: a
xs :: [a]
(:) :: b -> [b] -> [b] -- this is how you write an operator as a function
-- ps: we can name the type variables however we want ;-)
在右边写(xs:x)
或(:)xs x
-我希望你能看到这是一个问题
但如何解决这个问题呢??
有了这个(:)
操作符——遗憾的是你不能——但幸运的是,还有另一个操作符可以完成这个任务
我们如何找到它??
我可以给你提示-你要找的操作符有类型签名-
?? :: [a] -> [a] -> [a]
我们需要做的另一件事是把x
列成一个列表-这太简单了,我会破坏它的乐趣:只需把[x]
要找到运算符,您可能会找到一个很好的帮助不,编译器会告诉您这是不可能的 您混淆了列表的两种不同“视图”。为了明确我所说的内容,让我们定义一个不同的列表实现
data List a = Cons a (List a) | EmptyList
mylist :: List Char
mylist = Cons 'a' (Cons 'h' (Cons 'a' (Cons '!' EmptyList)))
oldlist :: [Char]
oldlist = 'a' : ('h' : ('a' : ('!' : [])))
-- or
oldlist = ['a','h','a','!']
-- alternatively you could write this as
oldlist = "aha!"
-- because `String` is just a list of `Char`.
在左侧,您可以编写您定义的新数据类型,在右侧,您可以提供所有运算符来构造此类类型或在函数定义中进行模式匹配
现在回到haskell内置列表类型——为了让事情变得更加明显,我将称之为“值级别”——变量x
,类型变量a
和(x:xs)
是列表中要匹配的两种模式,如下所示[]
对应于(x:xs)
,并且Cons x xs
至[]
空列表
是这些表达式的类型,对应于列表a
[a]
现在,当您尝试构建函数时,我们必须仔细查看
(x:xs)
,并检查模式匹配组件的类型以及该行的右侧
x :: a
xs :: [a]
(:) :: b -> [b] -> [b] -- this is how you write an operator as a function
-- ps: we can name the type variables however we want ;-)
在右边写(xs:x)
或(:)xs x
-我希望你能看到这是一个问题
但如何解决这个问题呢??
有了这个(:)
操作符——遗憾的是你不能——但幸运的是,还有另一个操作符可以完成这个任务
我们如何找到它??
我可以给你提示-你要找的操作符有类型签名-
?? :: [a] -> [a] -> [a]
我们需要做的另一件事是把x
列成一个列表-这太简单了,我会破坏它的乐趣:只需把[x]
要找到运算符,您可能会得到很大帮助您试过了吗?没有列表有两种形式
(a:[a])
和[]
。我不清楚您的目标是什么。给出一些您尝试编写的函数的输入/输出示例可能会更清楚。我正在重新创建函数反转(a:as)不是类型。使用同一个字母作为类型变量和给定类型的值可能会令人困惑。当您说invertor::[a]->[a]
,a
是一种类型,您说invertor
获取任何类型的元素列表a
,并返回相同给定类型的元素列表a
。接下来的两句话,您要说明函数如何在空列表[]
和至少一个元素列表(a:as)上工作
。在这种情况下,a
是a
类型的元素。您尝试过吗?没有列表有两种形式(a:[a])
和[]
。我不清楚您的目标是什么。给出一些有趣的输入/输出示例可能更清楚