Сопоставление с образцом на подмножестве моих данных в haskell - PullRequest
0 голосов
/ 15 июня 2019

Предположим, у меня есть структура:

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

У меня есть функция, которая ожидает MyType, и я хотел бы соответствовать только следующему подмножеству грамматики:

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

Я знаю, что это невозможно сделать в Хаскеле. Есть ли способ, которым я бы параметризовал структуру, чтобы как-то пометить узлы?

Может ли помочь Data.Void?

Ответы [ 2 ]

5 голосов
/ 15 июня 2019

Самое простое решение состоит в том, чтобы просто разделить ваши данные:

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

data MyType
  = CV Int
  | CNonV MyTypeNoCV

Если вы хотите быть более модным, вы можете использовать GADT, чтобы дать вашему типу данных индекс.Вот пример, где Ty индексируется как 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
2 голосов
/ 15 июня 2019

Если ваша функция не может обработать CV, она может вернуть Nothing. Вот упрощенный пример с двумя вариантами данных, которые могут продемонстрировать, чего вы хотите достичь

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

Затем в командной строке:

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