Haskell中不同类型的嵌套应用函子

Vla*_*mir 2 haskell functor monad-transformers applicative

我想制作不同类型的嵌套applicative functor.例如,不同类型的嵌套简单仿函数(在ghci中)可以正常工作:

Prelude> ((+2) <$>) <$> (Just [1..4])
Just [3,4,5,6]
Run Code Online (Sandbox Code Playgroud)

但对于不同类型的应用函子:

Prelude> ((*) <$>)  <$> (Just [1,2,3]) <*> (Just [4,5,6,7])

<interactive>:56:1: error:
    * Couldn't match type `[Integer -> Integer]' with `[Integer] -> b'
Run Code Online (Sandbox Code Playgroud)

不工作!我想获得这样的东西:

Just [4,5,6,7,8,10,12,14,12,15,18,21]
Run Code Online (Sandbox Code Playgroud)

我知道应用仿函数在仿函数和monad之间具有中间位置.在关于monad变形金刚的话题之前,我可以看到这个练习是初步的.

dan*_*iaz 5

除了嵌套升降机和fmaps之外,构建applicative functor的另一个选项是Data.Functor.Composenewtype:

newtype Compose f g a = Compose { getCompose :: f (g a) }
Run Code Online (Sandbox Code Playgroud)

例如:

ghci> let Compose result = (*) <$> Compose (Just [1,2,3]) <*> Compose (Just [4,5,6,7])
ghci> result
Just [4,5,6,7,8,10,12,14,12,15,18,21]
Run Code Online (Sandbox Code Playgroud)

Applicatives是如此良好,以至于单个newtype足以组成任何两个类型的实例.除了嵌套之外,还有其他方法可以将它们组合起来,比如ProductDay卷积:

data Product f g a = Pair (f a) (g a)

data Day f g a = forall b c. Day (f b) (g c) (b -> c -> a)
Run Code Online (Sandbox Code Playgroud)

Monad不过也不构成,所以我们需要为每个monad添加一个不同的 newtype,以便用第一个monad的能力增加其他monad.我们称之为newtypes monad变换器.