Создать запись со всеми полями неопределенными, без предупреждения - PullRequest
4 голосов
/ 08 апреля 2020

Я хотел бы создать значение типа записи, которое может быть сопоставлено с шаблоном, без заполнения каких-либо полей.

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

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

bar :: Bool
bar = fun MkFoo{}

Это работает, потому что все поля Foo переданы fun не определены, и fun ленив в них. Конечно, fun undefined потерпит неудачу, поскольку fun сопоставлений с образцом в конструкторе записи MkFoo.

Однако это вызывает предупреждение компилятора:

• Поля MkFoo не инициализирован: field1, field2

Я хотел бы избавиться от этого предупреждения для этого конкретного c экземпляра . Поэтому я не собираюсь отключать предупреждение вообще (с -Wno-missing-fields). Я также не собираюсь менять fun (я мог бы просто сделать сопоставление с шаблоном на MkFoo неопровержимым). Я также хотел бы избежать записи всех полей MkFoo, как в

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

1 Ответ

4 голосов
/ 08 апреля 2020

Как уже упоминалось в комментариях, одним из вариантов является использование обобщений, либо ванильной версии, либо вспомогательного пакета, например 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
...