代码之家  ›  专栏  ›  技术社区  ›  luochen1990

如何在Haskell中导出多个函子实例?

  •  4
  • luochen1990  · 技术社区  · 5 年前

    {-# language DeriveFunctor, DeriveFoldable, DeriveTraversable #-}
    
    -- | a general represetation of an expression
    -- , with ref info contained in r and two attributes contained in a1, a2
    data Expr r a1 a2
        = Ref r a1 a2
        | App FunName [Expr r a1 a2] a1 a2
        | Lit Value a1 a2
        deriving (Functor, Foldable, Traversable)
    

    正在使用 DeriveFunctor 只能帮我定义 instance Functor (Expr r a1) ,所以我可以 fmap 结束 a2 ,但如果我想的话 fmap 结束 a1 r ,我发现这是不可能使用的 用一个 newtype ,因为以下代码不起作用:

    newtype ExprR a1 a2 r = MkExprR { getExpr :: Expr r a1 a2 }
    
    deriving instance Functor (ExprR a1 a2)
    

    Bifunctor 可能是个好主意,而且确实有一些包 DeriveBifunctor 但是如果我们需要三个呢?我们需要吗 DeriveTrifunctor DeriveQuadfunctor

    如果我们需要的不仅仅是 Functor ? 考虑到 Foldable , Traversable

    这个问题有什么解决办法吗?在haskell实践中,人们如何解决这个问题?

    1 回复  |  直到 5 年前
        1
  •  1
  •   luqui    5 年前

    不是对你问题的直接回答,而是一个观察。如果这是您正在处理的实际类型,它可以使用一些因子分解。 a1 a2

    data ExprNode r a = ExprNode (ExprF r a) a
        -- it's a bifunctor
    
    data ExprF r a
        = Ref r
        | App FunName [ExprNode r a]
        | Lit Value
        -- it's a bifunctor
    
    type Expr r a1 a2 = ExprNode r (a1, a2)
    

    a1号 a2