我正在尝试实现一个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