首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用GHC泛型定义一个“m空”-like函数?

用GHC泛型定义一个“m空”-like函数?
EN

Stack Overflow用户
提问于 2019-12-29 09:39:35
回答 1查看 82关注 0票数 2

我正在为Zoho编写一个客户端库,并拥有一组具有所有Maybe a字段的不同记录类型,即:

代码语言:javascript
复制
data Approval = Approval
  { apDelegate :: Maybe Bool
  , apApprove :: Maybe Bool
  , apReject :: Maybe Bool
  , apResubmit :: Maybe Bool
  } deriving (Eq, Show, Generic)

data ContactSpecialFields = ContactSpecialFields
  { csfCurrencySymbol :: Maybe Text -- $currency_symbol
  , csfState :: Maybe Text -- $state
  , csfProcessFlow :: Maybe Bool -- $process_flow
  , csfApproved :: Maybe Bool -- $approved
  , csfApproval :: Approval  -- $approval
  , csfEditable :: Maybe Bool -- $editable
  } deriving (Eq, Show)

-- and so on

我需要一种方法来定义这类类型的“空”记录,例如:

代码语言:javascript
复制
emptyApproval :: Approval
emptyApproval = Approval
  { apDelegate = Nothing
  , apApprove = Nothing
  , apReject = Nothing
  , apResubmit = Nothing
  }

因此,我向GHC.Generics求助,得到了一些有用的东西(这是buggy!):

代码语言:javascript
复制
-- These parts seem logically correct to me...

class GEmptyZohoStructure f where
  gEmptyZohoStructure :: f p

instance (GEmptyZohoStructure f, GEmptyZohoStructure g) => GEmptyZohoStructure (f :*: g) where
  gEmptyZohoStructure = (gEmptyZohoStructure :: f p) :*: (gEmptyZohoStructure :: g p)

instance GEmptyZohoStructure Maybe where
  gEmptyZohoStructure = Nothing

class EmptyZohoStructure a where
  emptyZohoStructure :: a

  default emptyZohoStructure :: (Generic a, (GEmptyZohoStructure (Rep a))) => a
  emptyZohoStructure = GHC.Generics.to gEmptyZohoStructure

-- Whereas these parts are random type-class instances that I've written, just 
-- to get the code to compile.

instance (GEmptyZohoStructure f) => GEmptyZohoStructure (M1 i t f) where
  gEmptyZohoStructure = (gEmptyZohoStructure :: f p)

instance (GEmptyZohoStructure f) => GEmptyZohoStructure (K1 i (f p)) where
  gEmptyZohoStructure = gEmptyZohoStructure

instance EmptyZohoStructure Approval

当代码编译时,以下(可以理解)在运行时导致堆栈溢出:

代码语言:javascript
复制
ghci> emptyZohoStructure  :: Approval
*** Exception: stack overflow

我遵循在encode上提供的https://www.stackage.org/haddock/lts-12.1/base-4.11.1.0/GHC-Generics.html#g:12教程,在那里,由于参数被传递给encode函数,它允许一个人打开M1 / K1构造函数并构建一些有意义的递归层次结构。如何为用例编写泛型的M1 K1 K1(其中泛型函数实际上没有任何参数)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-29 13:01:39

在泛型类型中定义GEmptyZohoStructure Maybe是没有意义的。

代码语言:javascript
复制
class G f where 
  gempty' :: f p
instance (G f, G g) => G ( f :*: g) where 
  gempty' = gempty' :*: gempty'

instance G c => G (D1 x c) where
  gempty' = M1 gempty'
instance G s => G (C1 x s) where
  gempty' = M1 gempty'    
instance E t => G (S1 m (Rec0 t)) where -- the key instance
  gempty' = M1 (K1 gempty)

class E a where
  gempty :: a
  default gempty :: (Generic a, G (Rep a)) => a
  gempty = to gempty'    
instance E (Maybe a) where 
  gempty = Nothing

在此之后,您可以定义由可能值组成的任何产品类型。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59518275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档