创建所有字段未定义的记录,不触发警告
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{}
这是有效的,因为传递给 fun
的 Foo
的所有字段都是未定义的,并且 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
我想创建一个可以模式匹配的记录类型的值,而不填充任何字段。
data Foo = MkFoo
{ field1 :: Int
, field2 :: Bool
}
fun :: Foo -> Bool
fun MkFoo{..} = True
bar :: Bool
bar = fun MkFoo{}
这是有效的,因为传递给 fun
的 Foo
的所有字段都是未定义的,并且 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