Haskell 不能';t匹配预期类型';x';实际类型为“([Char]、[Char]、[Char])';

Haskell 不能';t匹配预期类型';x';实际类型为“([Char]、[Char]、[Char])';,haskell,Haskell,我创建了一个数据类型,用于存储关于一群人的信息:他们的姓名和出生日期。数据类型只是两个三元组列表,第一个列表保存名称(第一个、中间个、最后一个),第二个列表保存DOB(日、月、年)。您可以看到下面的数据类型(我省略了DOB类型,因为它与这个问题无关): 我试图编写一个函数来创建初始列表,因此它返回第一个人的名字,然后返回人的列表。到目前为止: initiallist :: ([String], People) initiallist = (first_name, all_people)

我创建了一个数据类型,用于存储关于一群人的信息:他们的姓名和出生日期。数据类型只是两个三元组列表,第一个列表保存名称
(第一个、中间个、最后一个)
,第二个列表保存DOB(日、月、年)。您可以看到下面的数据类型(我省略了DOB类型,因为它与这个问题无关):

我试图编写一个函数来创建初始列表,因此它返回第一个人的名字,然后返回
人的列表。到目前为止:

initiallist :: ([String], People)
initiallist = (first_name, all_people)
    where first_name = "Bob" : "Alice" : "George" : []
        all_people = People ("Bob","Alice","George") : []
这导致

error:
* Couldn't match expected type `Names'
     with actual type `([Char], [Char], [Char])'
* In the first argument of `People', namely `("Bob", "Alice", "George")'
  In the first argument of `(:)', namely
    `People ("Bob", "Alice", "George")'
  In the expression: People ("Bob", "Alice", "George") : []

现在,在我对Haskell的了解中,我认为
String
只是一个
[Char]
。因此,我认为我的代码可以很好地工作,但这绝对让我难堪。

与应用
人员
构造函数相比,
操作符的优先级更低。所以你的表达式实际上是:

all_people = (People ("Bob","Alice","George")) : []
错误消息中指出了
People
constructor应用于什么:

...first argument of `People', namely `("Bob", "Alice", "George")'
您必须明确说明:

all_people = People (("Bob","Alice","George")) : [])
或者,使用列表表示法:

all_people = People [("Bob","Alice","George")]

运算符的优先级低于应用
人员
构造函数。所以你的表达式实际上是:

all_people = (People ("Bob","Alice","George")) : []
错误消息中指出了
People
constructor应用于什么:

...first argument of `People', namely `("Bob", "Alice", "George")'
您必须明确说明:

all_people = People (("Bob","Alice","George")) : [])
或者,使用列表表示法:

all_people = People [("Bob","Alice","George")]

代码中有两个问题

第一种是,
People
数据类型接受
Names
数据类型,但您试图向其提供
[(字符串、字符串、字符串)]
数据类型

第二,正如@Koterpillar的回答中所提到的,值构造函数(这里的
人员
和/或
姓名
)的优先级高于列表值构造函数
(左关联)

另一点是可以通过
newtype
定义数据类型,从而生成更高效的代码

因此,请记住,值构造函数也是函数,如果您想使用
构造函数创建列表,您也可以这样做

newtype Names  = Names [(String, String, String)]
newtype People = People Names

initiallist :: ([String], People)
initiallist = (first_name, all_people)
    where first_name = "Bob" : "Alice" : "George" : []
          all_people = People $ Names $ ("Bob","Alice","George") : []
当然,你也可以喜欢

all_people = People (Names [("Bob","Alice","George")])

代码中有两个问题

第一种是,
People
数据类型接受
Names
数据类型,但您试图向其提供
[(字符串、字符串、字符串)]
数据类型

第二,正如@Koterpillar的回答中所提到的,值构造函数(这里的
人员
和/或
姓名
)的优先级高于列表值构造函数
(左关联)

另一点是可以通过
newtype
定义数据类型,从而生成更高效的代码

因此,请记住,值构造函数也是函数,如果您想使用
构造函数创建列表,您也可以这样做

newtype Names  = Names [(String, String, String)]
newtype People = People Names

initiallist :: ([String], People)
initiallist = (first_name, all_people)
    where first_name = "Bob" : "Alice" : "George" : []
          all_people = People $ Names $ ("Bob","Alice","George") : []
当然,你也可以喜欢

all_people = People (Names [("Bob","Alice","George")])