2012-09-09 95 views
1

我想將子數據類型傳遞到函數中。如何創建數據子類型

一個例子:

data Car a = Ford | Opel | BMW | Mercedes a deriving (Show) 

data Mercedes a = SClass a| CClass a| MClass a 


myfunc::Car->String 
myfunc a = show a ++ " works correctly" 

,但我做的:

MYFUNC CClass 「X」

它說

不在範圍:構造CClass

+4

這有多個錯誤。 「導出(Show)」應該具有大寫的「節目」。你的第二行似乎試圖成爲一種數據類型,但缺少「數據」關鍵字(可能是你的錯誤信息的原因)。如果你這樣做,那麼你的類型將會有問題,因爲你將有「福特」類型「汽車(梅賽德斯弦)」。告訴我們你想要達到的目標。 –

+0

此外,您需要在'myfunc'中使用'show',即'myfunc a = show a ++「正常工作。 – huon

+0

我希望能夠將任何汽車模型傳遞到一個功能中,並且該功能可以對汽車模型進行模式匹配並對每個模型進行不同的處理。 –

回答

11

爲了實現 「亞健康」 -types,一個有幾個選項。第一個就是使用更多data類型的,因爲你正在嘗試:

data Car a = Ford (Ford a) | Mercedes (Mercedes a) deriving (Show) 

data Ford a = ModelT a | Falcon a deriving (Show) -- different Fords models 
data Mercedes a = CClass a | SClass a deriving (Show) -- different Mercedes models 

注意,作爲一個類型構造是作爲一個數據構造不同,因此不能只用data Car = .. | Mercedes a:這是說,一個的方法使Car String只是說Mercedes "a",它與Mercedes類型沒有關係。現在,人們可以只使用類似功能:

horsepower :: Car a -> Float 
horsepower (Ford (ModelT _)) = 1 
horsepower (Ford (Falcon _)) = 500 
horsepower (Mercedes (CClass _)) = 300 
horsepower (Mercedes (SClass _)) = 400 

和你的例子是:


另一種方式,讓「子類型」這樣是使用類型類(根據具體情況,這可能是一個更好的選擇)。例如。

class (Show c) => Car c where 
    make :: String 
    model :: c -> String 
    horsepower :: c -> Float 
    number_of_seats :: c -> Int 
    -- etc. 

data Ford a = ModelT a | Falcon a deriving (Show) 
instance (Show a) => Car (Ford a) where 
    make = "Ford" 
    horsepower (ModelT _) = 1 
    horsepower (Falcon _) = 500 
    -- etc. 


data Mercedes a = CClass a | SClass a deriving (Show) 
instance (Show a) => Car (Mercedes a) where 
    make = "Mercedes" 
    horsepower (CClass _) = 300 
    horsepower (SClass _) = 400 
    -- etc. 

你的myfunc例子是:

myfunc :: (Car c) => c -> String 
myfunc c = (make `asTypeOf` c) ++ " " ++ show C++ " works correctly" 

-- myfunc (ModelT "A") => Ford ModelT "A" works correctly 
-- myfunc (CClass "b") => Mercedes CClass "b" works correctly 

另外請注意,必須調用功能,如function (Ford (Ford "a"))(或function (CClass "a"))用括號。

5

首先,你需要按如下定義您的汽車類型:

data Car a = ... | Mercedes (MercedesClass a) | ... 

data MercedesClass a = CClass a | ... 

...然後你可以寫:

myFunc (Mercedes (CClass "x")) 
+0

在myFunc中,我嘗試模式匹配(CClass a),但它說不能匹配預期類型Car a與實際類型MercedesClass a –

+0

@peroni_santo您必須在'let v'中對'Mercedes(CClass a)' –

+0

@peroni_santo進行模式匹配= CClass「x」'值'v'的類型爲'MercedesClass String'。然後,在'let c = Mercedes v'中,值'c'的類型爲'Car String'。 –