创建所有字段未定义的记录,不触发警告

Create record with all fields undefined, without triggering warning

我想创建一个可以模式匹配的记录类型的值,而不填充任何字段。

data Foo = MkFoo
    { field1 :: Int
    , field2 :: Bool
    }

fun :: Foo -> Bool
fun MkFoo{..} = True

bar :: Bool
bar = fun MkFoo{}

这是有效的,因为传递给 funFoo 的所有字段都是未定义的,并且 fun 在其中是惰性的。当然,fun undefined 会失败,因为 fun 模式匹配记录构造函数 MkFoo.

但是,这会导致编译器警告:

• Fields of MkFoo not initialised: field1, field2

我想删除此特定实例的警告。所以我一般不打算关闭警告(-Wno-missing-fields)。我也不打算更改 fun(我可以让 MkFoo 上的模式匹配无可辩驳)。我还想避免写出 MkFoo 的所有字段,如

bar = fun MkFoo{ field1 = undefined, field2 = undefined }

正如评论中提到的,一种选择是使用泛型,无论是原始版本还是像 generics-sop:

这样的辅助包
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-} -- derive stock, anyclass stuff
{-# LANGUAGE ImportQualifiedPost #-} -- GHC >= 8.10
import GHC.Generics
import Generics.SOP qualified as SOP
import Generics.SOP.NP (pure_NP)

data Foo
  = MkFoo
      { field1 :: Int,
        field2 :: Bool
      }
  deriving stock (Generic)
  deriving anyclass (SOP.Generic)

allundef :: Foo
allundef = SOP.productTypeTo $ pure_NP undefined