函数来处理多个现有独立的数据定义
我有多个数据定义,作为一个简单的例子:函数来处理多个现有独立的数据定义
data Fruit = Apple String Bool | Cherry String String
| Grape String
data Vegetable = Carrot String
| Onion Bool String
| Tomato String String
现在我想有应进行两种类型的函数,我想是这样的:
f :: a -> String f (Carrot s) = s
f (Apple s b) = s
f (Onion b s) = s
...
但是这不起作用,因为预期类型a
不能与例如类型Carrot
匹配。我想知道如何在模式匹配或其他技术的帮助下定义一个可以处理多个现有独立数据定义的函数。
回答:
做你正在尝试做的方法是与同时涉及食品新的数据类型,所以,让我们把它叫做食物,这将是:
data Food = Veg Vegetable | Fr Fruit deriving Show data Fruit = Apple String Bool
| Cherry String String
| Grape String deriving Show
data Vegetable = Carrot String
| Onion Bool String
| Tomato String String deriving Show
f :: Food -> String
f (Veg v) = fVeg v
f (Fr f) = fFruit f
fVeg (Carrot s) = s
fVeg (Onion b s) = s
fVeg (Tomato s1 s2) = s1 ++ s2
fFruit (Apple s b) = s
...
...
f $ Veg $ Onion True "friend"
=> "friend"
回答:
有两个选项。一个是Damian Lattenero说的,另一个选择是使用typeclasses。
class Food a where f :: a -> String
instance Food Fruit where
f (Apple ...) = ...
f (Cherry ...) = ...
f ...
instance Food Vegetable where
f (Carrot ...) = ...
f (Onion ...) = ...
f (Tomato ...) = ...
问题是你不能有,例如,食物的列表,因为水果和蔬菜是不同的类型。但是你可以在没有问题的情况下使用f。
编辑:
另一种选择,存在量化,以在列表中有两种类型,但是只将f应用到数据(也使用上面的代码):
{-# LANGUAGE ExistentialQuantification #-} data F = forall a. (Food a) => F a
instance Food F where
f (F x) = f x
xs :: [F]
xs = [F (Apple ...), F (Carrot ..), F (Tomato ...)]
的一个例子,函数使用F:
mapF :: [F] -> [String] mapF xs = map f xs
以上是 函数来处理多个现有独立的数据定义 的全部内容, 来源链接: utcz.com/qa/265718.html