开发者

Haskell pattern match on type

开发者 https://www.devze.com 2023-03-02 01:43 出处:网络
Is there any way of doing something like 开发者_Python百科this in haskell ? data Fruits = Apple Int | Orange Int deriving (Eq, Show)

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消