Haskell pattern match on type
Is there any way of doing something like 开发者_Python百科this in haskell ?
data Fruits = Apple Int | Orange Int deriving (Eq, Show)
basket = [Apple 2, Orange 4]
from_basket t (x:basket) =
case x of
(t i) -> i
_ -> from_basket t basket
Now i want to get the 'apple' from the list of fruits ( basket )
from_basket Apple basket
Without an explicit pattern match
case x of
Apple i -> ...
Orange i -> ...
_ ->
One way would be to define your own helper function isApple
and then do filtering:
isApple (Apple _) = True
isApple _ = False
getApples = filter isApple
Pattern matching is the tool of your choice, I don't know whether you can simplify this any further. But apart from some dirty template Haskell, I don't see any other way.
The other answers have explained why it won't work as is, but as far as alternatives go, wanting to do something like that is often a sign that your data types should look something more like this:
data FruitName = Apple | Orange deriving (Eq, Show)
data Fruits = Fruits FruitName Int deriving (Eq, Show)
...in which case the desired function becomes trivial.
You can accomplish something similar to this by defining selector functions
getApple :: Fruits -> Maybe Int
getApple (Apple x) = Just x
getApple _ = Nothing
getOrange :: Fruits -> Maybe Int
getOrange (Orange x) = Just x
getOrange _ = Nothing
fromBasket selector [] = Nothing
fromBasket selector (x:basket) =
case selector x of
Just x -> Just x
Nothing -> fromBasket selector basket
Now you can do
> fromBasket getApple basket
Just 2
> fromBasket getOrange basket
Just 4
This assumes that your constructors all take similar arguments. It also returns Nothing
if the desired fruit type was not in the basket.
精彩评论