Handling multiple types with the same internal representation and minimal boilerplate?

后端 未结 3 1229
小蘑菇
小蘑菇 2021-02-14 01:47

I find myself running into a problem commonly, when writing larger programs in Haskell. I find myself often wanting multiple distinct types that share an internal representatio

3条回答
  •  死守一世寂寞
    2021-02-14 02:36

    There's another straightforward approach.

    data MyGenType = Foo | Bar
    
    op :: MyGenType -> MyGenType
    op x = ...
    
    op2 :: MyGenType -> MyGenType -> MyGenType
    op2 x y = ...
    
    newtype MySpecialType {unMySpecial :: MyGenType}
    
    inMySpecial f = MySpecialType . f . unMySpecial
    inMySpecial2 f x y = ...
    
    somefun = ... inMySpecial op x ...
    someOtherFun = ... inMySpecial2 op2 x y ...
    

    Alternately,

    newtype MySpecial a = MySpecial a
    instance Functor MySpecial where...
    instance Applicative MySpecial where...
    
    somefun = ... fmap op x ...
    someOtherFun = ... liftA2 op2 x y ...
    

    I think these approaches are nicer if you want to use your general type "naked" with any frequency, and only sometimes want to tag it. If, on the other hand, you generally want to use it tagged, then the phantom type approach more directly expresses what you want.

提交回复
热议问题