如何使用泛型提取特定类型的所有值?

How can I use generics to extract all values of a particular type?

我有这样的数据类型:

data MyType = Foo Bool
            | Bar
            | Baz Bool (Maybe String) Bool
            | Quux Int String

我可以使用泛型来编写一个函数 getBools :: MyType -> [Bool] returns 输入中所有布尔字段的列表吗?

我想到了这个类型签名:

getAllOfType ::
  (Generic inner, Generic outer, HasDatatypeInfo inner, All2 HasDatatypeInfo (Code outer)) =>
  Proxy inner -> outer -> [inner]

使用generics-sop,但我认为这样不对。比较 DatatypeInfos 不会让类型检查器相信这两种类型是等价的。

使用uniplate:

{-# LANGUAGE DeriveDataTypeable #-}

module M where

import Data.Data
import Data.Generics.Uniplate.Data

data MyType
  = Foo Bool
  | Bar
  | Baz Bool (Maybe String) Bool
  | Quux Int String
  deriving Data

getBools :: MyType -> [Bool]
getBools = universeBi