【问题标题】:Writing classy lenses for records with type families?为类型家族的唱片写优雅的镜头?
【发布时间】:2018-08-15 08:50:57
【问题描述】:

Lenses and TypeFamiliesHow to derive instances for records with type-familiesHow to make lenses for records with type-families 相关

每次我热情地尝试使用类型族来减少一些样板代码时,我都会把自己编程到一个角落里。这是最新的——如何在下面给出的代码 sn-p 中为 RecordPoly f 定义镜头?

{-# LANGUAGE TemplateHaskell, DeriveGeneric, MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances, DataKinds #-}
module Try where

import Control.Lens

data PGInt
data PGText

data Selector = Haskell | DB


type family DBField (f :: Selector) hask db where
  DBField 'Haskell hask _ = hask
  DBField 'DB _ db = db

data RecordPoly f = RecordPoly
  { recFieldA :: !(DBField f Int PGInt)
  , recFieldB :: !(DBField f String PGText)
  }

class HasFieldA s a | s -> a where fieldA :: Lens' s a

instance HasFieldA (RecordPoly 'Haskell) Int where
  fieldA fctor (RecordPoly fa fb) = fmap (\x -> RecordPoly x fb) (fctor fa)

失败并出现以下错误:

• Illegal instance declaration for ‘HasFieldA (RecordPoly f) a’
    The liberal coverage condition fails in class ‘HasFieldA’
      for functional dependency: ‘s -> a’
    Reason: lhs type ‘RecordPoly f’ does not determine rhs type ‘a’
    Un-determined variable: a
• In the instance declaration for ‘HasFieldA (RecordPoly f) a’

似乎唯一可行的是:

instance HasFieldA (RecordPoly 'Haskell) Int where
  fieldA fctor (RecordPoly fa fb) = fmap (\x -> RecordPoly x fb) (fctor fa)

这是使它工作的唯一方法(从而导致一种新的样板爆炸)?这段代码的类似多态版本是如何工作的,但在使用类型族时却不行:

data RecordPoly fa fb = RecordPoly
  { recFieldA :: fa
  , recFieldB :: fb
  }

class HasFieldA s a | s -> a where fieldA :: Lens' s a

instance HasFieldA (RecordPoly fa fb) fa where
  fieldA fctor (RecordPoly fa fb) = fmap (\x -> RecordPoly x fb) (fctor fa)

【问题讨论】:

    标签: haskell haskell-lens type-families


    【解决方案1】:

    终于明白了……

    instance (fa ~ DBField f Int PGInt) => HasFieldA (RecordPoly f) fa where
      fieldA fctor (RecordPoly fa fb) = fmap (\x -> RecordPoly x fb) (fctor fa)
    

    【讨论】:

      猜你喜欢
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      • 2011-03-08
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多