How to put constraints on the associated data?

后端 未结 3 1354
温柔的废话
温柔的废话 2021-02-19 06:43

I would like to state that the associated data is always an instance of a certain class.

class (Context (Associated a b)) => Class a where
  data Associated a         


        
3条回答
  •  别那么骄傲
    2021-02-19 07:11

    As was pointed out by @SjoerdVisscher, using forall on the left side of => in a class or instance is actually not ok, at least not yet, though my specific example does work in ghc-7.4.


    This way it seems to work:

    {-# LANGUAGE FlexibleInstances    #-}
    {-# LANGUAGE TypeFamilies         #-}
    {-# LANGUAGE Rank2Types           #-}
    {-# LANGUAGE ConstraintKinds      #-}
    {-# LANGUAGE UndecidableInstances #-}
    
    class Context c where
      func1 :: c -> String
    
    class (forall b. Context (Associated a b)) => Class a where
      data Associated a :: * -> *
    
    newtype ClassTest = ClassTest { runClassTest :: String }
    
    instance (forall b. Context (Associated ClassTest b)) => Class ClassTest where
      data Associated ClassTest b = ClassTestAssoc b (b -> ClassTest)
    
    instance Context (Associated ClassTest b) where
      func1 (ClassTestAssoc b strFunc) = runClassTest $ strFunc b
    
    main = putStr . func1 $ ClassTestAssoc 37 (ClassTest . show)
    

    The extra forall b constraint in the instance seems a bit ugly and redundant, but apparently it's necessary.

    $ runghc-7.4.1 tFamConstraint0.hs
    37

提交回复
热议问题