如何创建数据子类型

per*_*nto 1 haskell

我想将子数据类型传递给函数.

一个例子:

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"
Run Code Online (Sandbox Code Playgroud)

但是我愿意:

myfunc CClass"x"

它说

不在范围内:构造函数CClass

huo*_*uon 11

要实现"子"类型,可以选择一些.第一种是在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
Run Code Online (Sandbox Code Playgroud)

请注意,作为一个类型构造函数不同于作为数据构造函数,因此不能只使用data Car = .. | Mercedes a:这就是说,制作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
Run Code Online (Sandbox Code Playgroud)

你的例子是:

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

-- myfunc (Ford (ModelT "A")) => Ford (ModelT "A") works correctly
-- myfunc (Mercedes (CClass "b")) => Mercedes (CClass "b") works correctly
Run Code Online (Sandbox Code Playgroud)

允许"subtyping"这样的另一种方法是使用类型类(取决于具体情况,这可能是更好的选择).例如

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.
Run Code Online (Sandbox Code Playgroud)

你的例子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
Run Code Online (Sandbox Code Playgroud)

另请注意,必须使用括号调用function (Ford (Ford "a"))(或function (CClass "a"))函数.


Gab*_*lez 5

首先,您需要按如下方式定义您的汽车类型:

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

data MercedesClass a = CClass a | ...
Run Code Online (Sandbox Code Playgroud)

......然后你可以写:

myFunc (Mercedes (CClass "x"))
Run Code Online (Sandbox Code Playgroud)