有没有办法将Maybe构造函数应用于泛型的每个记录领域? [英] Is there a way to apply Maybe constructor to each field of record with generics?

查看:117
本文介绍了有没有办法将Maybe构造函数应用于泛型的每个记录领域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两种数据类型,第二种是第一种,但在每个字段上都有可能。

  data A = {a :: Int,b :: String} 
data B = {c :: Maybe Int,d :: Maybe String}

有没有一种方法可以创建一个函数

  f :: A  - > ; B 
g :: B - > A - > A

没有关于字段本身的任何知识? (如果第一个参数的值不是 g 将从第二个参数取值)

div>

这可以通过泛型-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆