Haskell 如何简化我的;产品「;几个算术类型构造函数的类型类?
请原谅我可能误用了下面的范畴理论术语。如果我似乎有一半的线索,我会判断自己是多么成功 我发现自己编写了一系列类来处理多个算术类型构造函数的产品。大概是这样的:Haskell 如何简化我的;产品「;几个算术类型构造函数的类型类?,haskell,Haskell,请原谅我可能误用了下面的范畴理论术语。如果我似乎有一半的线索,我会判断自己是多么成功 我发现自己编写了一系列类来处理多个算术类型构造函数的产品。大概是这样的: import Control.Applicative -- | RWS monad. newtype RWS r w s a = RWS {runRWS :: r -> s -> (a, s, w)} -- | A class for unary type constructors that support a Carte
import Control.Applicative
-- | RWS monad.
newtype RWS r w s a = RWS {runRWS :: r -> s -> (a, s, w)}
-- | A class for unary type constructors that support a Cartesian
-- product operation.
class ProductObject f where
(***) :: f a -> f b -> f (a, b)
infixr ***
-- | Example instance of 'ProductObject'.
instance ProductObject [] where
(***) = liftA2 (,)
-- | A class for binary type constructors (read as morphisms
-- between their type parameters) that support a product morphism
-- operation.
class ProductMorphism arrow where
(****) :: arrow a b -> arrow c d -> arrow (a, c) (b, d)
infixr ****
-- | Example instance of 'ProductMorphism'.
instance ProductMorphism (->) where
f **** g = \(a, c) -> (f a, g c)
-- | A class for ternary type constructors (read as two-place
-- multiarrows @a, b -> c@) with products.
class ProductMultimorphism2 arr2 where
(*****) :: arr2 a b c -> arr2 d e f -> arr2 (a, d) (b, e) (c, f)
infixr *****
-- | A class for ternary type constructors (read as two-place
-- multiarrows @a, b -> c@) with products.
class ProductMultimorphism3 arr3 where
(******) :: arr3 a b c d -> arr3 e f g h -> arr3 (a, e) (b, f) (c, g) (d, h)
infixr ******
-- | Let's pretend that the 'RWS' monad was not a type synonym
-- for 'RWST'. Then an example of 'ProductMorphism3' would be:
instance ProductMultimorphism3 RWS where
f ****** g = RWS $ \(fr, gr) (fs, gs) ->
let (fa, fs', fw) = runRWS f fr fs
(ga, gs', gw) = runRWS g gr gs
in ((fa, ga), (fs', gs'), (fw, gw))
现在,这是恼人的几个原因。最大的一个问题是,我必须修改应用程序中的一个类型以添加第三个参数,这意味着现在我必须找到该类型的***
的所有用法,并将它们更改为***
有什么办法可以缓解这种情况吗?我试图了解GHC中的
polytypes
是否适用于此,但(a)进展缓慢,(b)我听说GHC 7.4.x中的polytypes
是有缺陷的。好吧,我自己已经弄明白了:
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}
import Control.Applicative
class Product f g where
type Prod a b :: *
(***) :: f -> g -> Prod f g
instance Product [a] [b] where
type Prod [a] [b] = [(a, b)]
(***) = liftA2 (,)
instance Product (a -> b) (c -> d) where
type Prod (a -> b) (c -> d) = (a, c) -> (b, d)
f *** g = \(a, c) -> (f a, g c)