Phi*_*sky 6 haskell functor category-theory
最近我不得不写下面这个函数:
mToL :: Maybe [a] -> [Maybe a]
mToL Nothing = []
mToL (Just xs) = map Just xs
Run Code Online (Sandbox Code Playgroud)
这就提出了一个问题:是否有可能将上述内容概括为:
transposeF :: (Functor f, Functor g) => f (g a) -> g (f a)
Run Code Online (Sandbox Code Playgroud)
我想,如果有一种方法来"崩溃"它只能f (g a)进f a,或有任何其他方式?
Nik*_*kov 13
该Traversable类型类提供sequence和sequenceA运营,提供最通用的解决你的问题,但它们需要不同的约束:
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
Run Code Online (Sandbox Code Playgroud)
aco*_*mar 10
这一般是不可能的,不是.设置f要Const b和g到Identity.
newtype Const b a = Const { getConst :: b }
newtype Identity a = Identity { runIdentity :: a }
Run Code Online (Sandbox Code Playgroud)
这些都是具有正常实例的显然算子.transposeF无法工作,因为Const b不提供任何a用于包装身份的s.所以你不能写转置函数.
另一方面,这对于很多Functor配对来说都很不错.分类概念是伴随仿函数的概念,一旦你看到它们,你就会开始到处看到它们.它们本身就是一个非常强大的概念.
实际上,有一个类型类可以支持这个.它不包含在标准类型类中,但"可表示的仿函数"具有此功能.
代表性的仿函数是一个F有两件事的仿函数
AF和之间的同构(->) A我们可以将此表示为
type family ReprObj (f :: * -> *):: *
class Functor f => Repr f where
toHom :: f a -> (ReprObj f -> a)
fromHom :: (ReprObj f -> a) -> f a
Run Code Online (Sandbox Code Playgroud)
哪里toHom . fromHom = fromHom . toHom = id.可表示的仿函数的一个例子,
newtype Pair a = Pair (a, a) deriving Functor
type instance ReprObj Pair = Bool
instance Repr Pair where
toHom (Pair (a, b)) True = a
toHom (Pair (a, b)) False = b
fromHom f = Pair (f True, f False)
Run Code Online (Sandbox Code Playgroud)
现在使用这个我们可以推导出来
swap :: (Functor f, Functor g, Repr f, Repr g) => f (g a) -> g (f a)
swap g = fromHom $ \obj -> fmap ($ obj) hom
where hom = fmap toHom g
Run Code Online (Sandbox Code Playgroud)
事实上,我们也可以从可表示的仿函数中获得一个免费的applicative和monad实例.我详细介绍了如何在博文中做到这一点.