有没有办法将Maybe构造函数应用于泛型的每个记录领域? [英] Is there a way to apply Maybe constructor to each field of record with generics?
问题描述
我有两种数据类型,第二种是第一种,但在每个字段上都有可能。
data A = {a :: Int,b :: String}
data B = {c :: Maybe Int,d :: Maybe String}
有没有一种方法可以创建一个函数
f :: A - > ; B
g :: B - > A - > A
没有关于字段本身的任何知识? (如果第一个参数的值不是 g
将从第二个参数取值)
这可以通过泛型-sop 来完成,一个扩展了GHC的默认泛型机制的库。
generics-sop可以定期记录并推导出一个通用的表示形式。该表示具有封装每个字段的类型参数,并且该库允许应用
{ - #hsequencerel =nofollow noreferrer>序列式操作。语言TypeOperators# - }
{ - #language DeriveGeneric# - }
{ - #language TypeFamilies# - }
{ - #language DataKinds# - }
import合格GHC.Generics as GHC
import Generics.SOP
data A = A {a :: Int,b :: String}派生(Show,GHC.Generic)
实例泛型A - 此泛型来自泛型 - sop
defaulty ::(通用a,代码a〜'[xs])=> NP也许xs - > a - >
defaulty maybes r =
的情况(从r)SOP(Z np) - > (SOP(Z结果))
main :: IO()
main(1)让结果= hliftA2(\mi->也许我是m)maybes np
in = do
print $ defaulty(Nothing:* Justbar:* Nil)(A 99foo)
Nothing:*只是bar:* Nil
是一种通用表示法,它与原始记录定义中的字段列表相匹配。注意表示中的每个字段都包含在 Maybe
中。
请参阅此处为泛型的另一个示例。
I have two data types and the second one is the copy of first, but with Maybe on each field.
data A = {a :: Int, b :: String}
data B = {c :: Maybe Int, d :: Maybe String}
Is there a way to make a functions
f :: A -> B
g :: B -> A -> A
without any knowledge about fields itself? (if value of first argument is nothing g
will take default value from second argument)
This can be done with generics-sop, a library that extends the default Generics machinery of GHC.
"generics-sop" can take a regular record and deduce a generic representation for it. This representation has a type parameter that wraps every field, and the library allows Applicative sequence-like operations across the record fields.
{-# language TypeOperators #-}
{-# language DeriveGeneric #-}
{-# language TypeFamilies #-}
{-# language DataKinds #-}
import qualified GHC.Generics as GHC
import Generics.SOP
data A = A {a :: Int, b :: String} deriving (Show,GHC.Generic)
instance Generic A -- this Generic is from generics-sop
defaulty :: (Generic a, Code a ~ '[ xs ]) => NP Maybe xs -> a -> a
defaulty maybes r = case (from r) of
SOP (Z np) -> let result = hliftA2 (\m i -> maybe i I m) maybes np
in to (SOP (Z result))
main :: IO ()
main = do
print $ defaulty (Nothing :* Just "bar" :* Nil) (A 99 "foo")
Nothing :* Just "bar" :* Nil
is a generic representation that matches the list of fields in the original record definition. Notice that each field in the representation is wrapped in Maybe
.
See here for another example of generics-sop.
这篇关于有没有办法将Maybe构造函数应用于泛型的每个记录领域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!