错误:没有来自文字的(Num Price)实例

时间:2017-02-25 12:50:47

标签: haskell algebraic-data-types

我正在为Haskell做准备而我正在努力创建电影商店。

我创建了类型CodeNameGenrePrice,元组Movie和元组列表Movies,当我尝试在tableMovies添加电影时会显示消息:

Prelude> :l movies
[1 of 1] Compiling Main             ( movies.hs, interpreted )

movies.hs:11:45:
    No instance for (Num Price) arising from the literal `50'
    Possible fix: add an instance declaration for (Num Price)
    In the expression: 50
    In the expression: (1, "Movie 1", "Adventure", 50)
    In the expression:
      [(1, "Movie 1", "Adventure", 50), (2, "Movie 2", "Horror", 30)]
Failed, modules loaded: none.
Prelude>

我的代码:

type Code = Integer
type Name = String
type Genre = String
data Price = Integer | Float

type Movie = (Code, Name, Genre,Price)

type Movies = [(Movie)]

tableMovies :: Movies
tableMovies = [ (001,"Movie 1", "Adventure",50)
             , (002,"Movie 2", "Horror", 30)]

我找到了这个问题的答案,但我无法理解,因为代码对我来说非常复杂。我只是在Haskell上开始

2 个答案:

答案 0 :(得分:4)

data Price = Integer | Float

这一行创建了三件事:类型Price,常量IntegerFloat。它的工作原理如下:

data Bool = False | True

在您的情况下,您有新值Integer(类型为Price)和Float(类型为Price)。这些与类型 IntegerFloat无关。 50不是Price类型的值(Price只有两个可能的值)。

整个事情有点令人困惑,因为类型和值存在于不同的命名空间中。您可以使用名为X的类型和名为X的值,它们彼此无关(或者在您的情况下,名为Integer的类型和名为{{1的值) }})。

要创建包含整数或浮点数的类型,可以执行以下操作:

Integer

现在您可以执行data Price = PriceInteger Integer | PriceFloat Float ,它将具有PriceInteger 50类型(但您仍然无法使用裸Price)。 <{1}}可能更容易,而且不允许浮动。

答案 1 :(得分:1)

FloatInteger位于data声明的右侧 - 您可以将它们视为与类型相比的不同宇宙的公民,因为它们是构造函数,即事物做一个类型。

如果您希望总和类型为IntegerFloat,则必须

data Price = I Integer | F Float deriving (Eq,Show)

但最好将货币值表示为来自Rational的{​​{1}}或来自scientificData.Ratio,并使用formatting包来进行字符串表示固定精度。

Scientific