Haskell 使用data关键字定义类型但获取多个声明错误

Haskell 使用data关键字定义类型但获取多个声明错误,haskell,Haskell,我正在为我正在编写的API包装器列出所有数据类型。我想分别创建每种类型,然后将它们合并到一个组中,这样我就可以模糊地引用它们 例如 这样,我可以定义如下内容: retrieveFromAPI :: APIObject a => String -> a 其中String是一个URL 但是,当我尝试编译此文件时,会出现两个错误: [1 of 1] Compiling Main ( API.hs, interpreted ) API.hs:28:16:

我正在为我正在编写的API包装器列出所有数据类型。我想分别创建每种类型,然后将它们合并到一个组中,这样我就可以模糊地引用它们

例如

这样,我可以定义如下内容:

retrieveFromAPI :: APIObject a => String -> a
其中
String
是一个URL

但是,当我尝试编译此文件时,会出现两个错误:

[1 of 1] Compiling Main             ( API.hs, interpreted )

API.hs:28:16:
    Multiple declarations of `Bookmark'
    Declared at: API.hs:22:17
                 API.hs:28:16

API.hs:28:27:
    Multiple declarations of `Note'
    Declared at: API.hs:27:13
                 API.hs:28:27
Failed, modules loaded: none.
我应该做些什么不同的事情


谢谢

问题在于
APIObject
,它的构造函数是
Bookmark
Note
,但它们也是
Bookmark
Note
数据类型的构造函数!相反,你可以这样做

data APIObject = BM Bookmark | NT Note
现在您有了一个构造函数
BM::Bookmark->APIObject
和一个构造函数
NT::Note->APIObject


或者,如果您不打算向
APIObject
添加更多类型,您可以这样做

type APIObject = Either Bookmark Note
因为
被定义为

data Either a b = Left a | Right b

因此,它与您尝试执行的操作是同构的。

问题在于
APIObject
,您有它的构造函数作为
Bookmark
Note
,但它们也是
Bookmark
Note
数据类型的构造函数!相反,你可以这样做

data APIObject = BM Bookmark | NT Note
现在您有了一个构造函数
BM::Bookmark->APIObject
和一个构造函数
NT::Note->APIObject


或者,如果您不打算向
APIObject
添加更多类型,您可以这样做

type APIObject = Either Bookmark Note
因为
被定义为

data Either a b = Left a | Right b

因此,这与你正在尝试做的事情是同构的。

Hmm,尝试完成第一步的最后一部分。如何将这些构造函数组合在一起?我是否需要将任何
书签
/
注释
实例包装为适当的BM/NT类型,以便通用地使用它?@Dan是的,您必须将它们包装在其他构造函数中。Haskell不允许你免费创建求和类型。明白了。为什么我不能这样做:
data APIObject=Bookmark{url::t.Text,title::t.Text}注意{author::t.Text,Text::t.Text}
?@实际上你可以,但建议不要这样做。我个人认为它根本不应该被允许,除非每个构造函数都有完全相同的字段。原因是类型系统可能允许
作者(书签“www.example.com”“example”)
,但这会导致运行时错误。Haskell的目的是让编程更安全,但不一定更容易(尽管它经常是),所以你应该选择一条更安全的路线,而不是一条“更好”的路线。嗯,试着解决第一步的最后一部分。如何将这些构造函数组合在一起?我是否需要将任何
书签
/
注释
实例包装为适当的BM/NT类型,以便通用地使用它?@Dan是的,您必须将它们包装在其他构造函数中。Haskell不允许你免费创建求和类型。明白了。为什么我不能这样做:
data APIObject=Bookmark{url::t.Text,title::t.Text}注意{author::t.Text,Text::t.Text}
?@实际上你可以,但建议不要这样做。我个人认为它根本不应该被允许,除非每个构造函数都有完全相同的字段。原因是类型系统可能允许
作者(书签“www.example.com”“example”)
,但这会导致运行时错误。Haskell旨在使编程更安全,但不一定更容易(尽管经常如此),因此您应该选择更安全的路线,而不是“更好”的路线。