所以我被告知列表有两种形式:
(a:as)
,其中a
是头部,as
是尾部
[a]
,其中a
是列表
我的问题是,如果我正在处理inverte :: [a]->[a]
我在定义函数时可以使用类型(a:as)
;
例如
inverte::[a]->[a]
inverte [] =[]
inverte (a:as) = (as:a)
答案 0 :(得分:3)
不,编译器会告诉你这是不可能的!
你正在混淆两种不同的观点"列表。为了说明我所说的内容,让我们定义一个不同的列表实现。
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 - 为了使事情更加明显,我将调用"值级别" -variables x
和类型变量{{1 }}
a
和(x:xs)
是列表中匹配的两种模式,此处
[]
对应(x:xs)
和Cons x xs
至[]
Emptylist
是这些表达式的类型,对应List a
。
现在,当您尝试构建函数[a]
时,我们必须仔细查看inverte
- 并检查模式匹配的组件类型以及右侧线。
(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
要找到您的运营商,您可能会发现hoogle一个很好的帮助
答案 1 :(得分:0)
那会失败。为清晰起见,我将使用不同的变量名称重写您的最后一行:
inverte (x:xs) = (xs:x)
变量x
的类型为a
,但变量xs
的类型为[a]
(即a
的列表。{{1运算符要求它的第一个参数是一个元素,第二个参数是一个相同类型的列表。所以交换它们不会工作。
合法(但缓慢)的方式是说:
。您可能还想查看this answer to a similar question。