2017-02-25 32 views
0

產生我正在實踐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)] 

我發現這個問題的一些答案,但我無法理解,因爲代碼對我來說非常複雜。我纔剛剛開始在哈斯克爾

回答

4
data Price = Integer | Float 

該行創建三兩件事:類型Price,和常量IntegerFloat。它的工作原理完全一樣:

data Bool = False | True 

你的情況,你有新的價值觀Integer(類型Price)和Float(的Price型)。這些與類型IntegerFloat無關。並且50不是Price類型的值(Price只有兩個可能的值)。

整個事情有點混亂,因爲類型和值存在於不同的命名空間。你可以有一個叫做X的類型和一個叫做X的值,它們之間沒有任何關係(或者你的情況,一種叫做Integer的類型和一個叫做Integer的值)。

要創建包含整數或浮點數類型,你可以這樣做:

data Price = PriceInteger Integer | PriceFloat Float 

現在你可以做PriceInteger 50,它將有型Price(但你仍然不能使用裸50)。僅僅做type Price = Integer並且不允許漂浮物可能更容易。

1

FloatInteger對你的data聲明的右邊 - 你可以將它們作爲不同的宇宙的公民相比,類型,因爲它們的構造,即東西,讓一個類型。

如果你想擁有的Integer之類型和Float你必須

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

但是,這將是最好的代表貨幣價值從Data.Ratio要麼RationalScientificscientific和使用formatting包進行固定精度的字符串表示。

import Data.Ratio (Rational) 
import Formatting 

newtype Price = Price {getPrice :: Rational} 
instance Show Price where 
    show (Price p) = formatToString (fixed 2) p