为什么Haskell抛出'无法构造无限类型'错误?

Zai*_*aid 2 haskell type-inference

我在Haskell中编写了以下代码来计算两个向量的点积,但由于以下错误而无法编译它:

cannot construct infinite type: a = [a] When generalising the type(s) for dot'

dot :: (Num a) => [a] -> [a] -> a

[] `dot` [] = 0
x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)
Run Code Online (Sandbox Code Playgroud)

我事先看过这个问题以获得指导.据我所知,类型是正确的.x,y和两个[]是列表,函数返回一个数字.

怎么了?

Ste*_*202 8

Ganesh的回答很明显.让我简要阐述一下"无限型"的含义.

dot 有这种类型定义:

dot :: (Num a) => [a] -> [a] -> a
Run Code Online (Sandbox Code Playgroud)

这意味着dot需要两个Num元素列表并返回一个Num.您的定义包括以下行:

x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)
Run Code Online (Sandbox Code Playgroud)

由于如内甚指出的那样,[xi,xs]是由两个元素的列表,xi并且xs应该是Num秒.同样的yiys.但随后它们作为参数传递给dot:

xs `dot` ys
Run Code Online (Sandbox Code Playgroud)

这意味着,xsys必须的名单Num秒.这导致了矛盾.


另一种看待这种情况的方法是暂时忘掉它的类型定义dot.这条线,

x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)
Run Code Online (Sandbox Code Playgroud)

dot采用两个列表的状态,其元素是适当的参数dot.但唯一有意义的方法是,这些列表是否是无限嵌套的.这是不允许也不明智的.


GS *_*ica 7

您将[x, y]使用将列表拆分为第一个元素和列表其余部分的语法混淆了两个元素列表的语法(x:y).试试这个:

dot :: (Num a) => [a] -> [a] -> a

[] `dot` [] = 0
x@(xi:xs) `dot` y@(yi:ys) = xi*yi + (xs `dot` ys)
Run Code Online (Sandbox Code Playgroud)

@顺便说一句,这些模式也是不必要的.