在同一个类

时间:2016-07-13 21:06:28

标签: haskell tuples typeclass functor

我正在尝试实现一个Unzippable类,用于解压缩嵌套在 m 仿函数中的 n -tuples。

此实现表现良好:

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}

class Unzippable tp where
  unzip   :: (Functor f)
             => f tp -> Unzipped f tp
  unzip'  :: (Functor f, Functor g, Unzippable (Unzipped g tp))
             => f (g tp) -> Unzipped f (Unzipped g tp)
  {- unzip'' etc... -}
  -----------------------------------
  unzip' x = unzip (unzip <$> s)
  {- implicit implementation for unzip'' etc... -}


type family Unzipped (f :: * -> *) tp where
  Unzipped f (a1, a2)      = (f a1, f a2)
  Unzipped f (a1, a2, a3)  = (f a1, f a2, f a3)
  {- ... -}

instance Unzippable (a1, a2) where
  unzip x = (fst <$> x, snd <$> x)

instance Unzippable (a1, a2, a3) where
  unzip x = ((\(a,_,_) -> a) <$> x, 
             (\(_,a,_) -> a) <$> x, 
             (\(_,_,a) -> a) <$> x)

测试它做了它应该做的事情:

λ> let x = [(1,2,3),(1,2,3)]
λ> let y = [x,x,x]
λ> unzip' y
([[1,1],[1,1],[1,1]],[[2,2],[2,2],[2,2]],[[3,3],[3,3],[3,3]]) 

我的问题:是否可以为类Unzippable实现非元组类型的实例?我试图通过单个函数(在我的例子中是一个后缀运算符,例如(-<) = unzip')隐藏可能的解压缩一些通用的高阶函数接口。

以下尝试:

{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances #-}

type family Unzipped (f :: * -> *) tp where
  {- ... -}
  Unzipped f a1 = f a1

instance Unzippable a1 where
  unzip x = x

给出错误:

• Couldn't match expected type ‘Unzipped f a1’
              with actual type ‘f a1’
• In the expression: x
  In an equation for ‘unzip’: unzip x = x
  In the instance declaration for ‘Unzippable a1’
• Relevant bindings include
    x :: f a1 
    unzip :: f a1 -> Unzipped f a1

0 个答案:

没有答案