简体   繁体   中英

Pattern matching on a subset of my data in haskell

Suppose I have a structure:

data MyType 
  = CV Int 
  | CA MyType MyType
  | CI
  | CD
  | CB

I have a function which expects MyType and I would like to match the following subset of the grammar only:

data MyTypeNoCV 
  = CA MyType MyType
  | CI
  | CD
  | CB

I know this isn't possible to do in Haskell. Is there a way I would parametrize the structure to somehow tag the nodes?

Could Data.Void possibly help?

The simplest solution is to just split up your data:

data MyTypeNoCV 
  = CA MyType MyType
  | CI
  | CD
  | CB

data MyType
  = CV Int
  | CNonV MyTypeNoCV

If you want to be more fancy, you can use GADTs give your data type an index. Here is an example where Ty is indexed by an Index .

{-# LANGUAGE DataKinds, GADTs, KindSignatures #-}

data Index = IsBaz | NotBaz

data Ty :: Index -> * where
  Foo :: Ty NotBaz
  Bar :: Ty NotBaz
  Baz :: Ty IsBaz

f :: Ty NotBaz -> Bool
f Foo = True
f Bar = False

If your function is not able to process CV, then it can return Nothing . Here's a simplified example with just 2 options of data, that might demonstrate what you're looking to accomplish

data MyType = CV | CA

process :: MyType -> Maybe String
process CV = Nothing
process CA = Just "Got CA!"

main = do
  putStrLn "Processing CA"

  case process CA of
    Nothing -> putStrLn "Nothing"
    Just x -> putStrLn x

  putStrLn "Processing CV"

  case process CV of
    Nothing -> putStrLn "Nothing"
    Just x -> putStrLn x

Then on the command line:

$ runhaskell script.hs
Processing CA
Got CA!
Processing CV
Nothing

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM