haskell - 为什么 "fmap (replicate 3) Just"的类型为 "a -> [Maybe a]",在 Haskell 中

标签 haskell types functor

最近我正在通过Learn You a Haskell for Great Good在线学习Haskell .

我有两个问题:

  • fmap (replicate 3)Functor f=> f a -> f [a] 类型.为什么可以应用到Just ?
  • 此外,为什么 fmap (replicate 3) Just类型 a -> [Maybe a] ,而不是 a -> Maybe [a] 类型?
  • 最佳答案

    如果您意识到自己是 fmap,这很容易理解。 -ing over 是一个函数,而不是 Maybe a值(value)。 Just的类型是 a -> Maybe a ,所以它落在 (->) a仿函数,而不是 Maybe仿函数。 Functor 的实例对于函数看起来像

    instance Functor ((->) a) where
        fmap g f = g . f
    

    所以fmap就变成了正常的功能组合!这意味着
    fmap (replicate 3) Just
    

    是相同的
    replicate 3 . Just
    

    很明显的类型为 a -> [Maybe a]
    一个更“类型代数”的解释是排列类型并替换,直到你不能了。让我们从我们的类型开始,但使用不同的变量名称以便于理解:
    fmap      :: Functor f => (a -> b) -> (f a -> f b)
    replicate :: Int -> c -> [c]
    Just      :: x -> Maybe x
    

    然后为 fmap (replicate 3) :
         (replicate 3) :: c -> [c]
    fmap               :: (a -> b) -> (f a -> f b)
    

    所以
    (c -> [c]) ~ (a -> b)
    

    这意味着
    c   ~ a
    [c] ~ b
    b   ~ [a]
    

    所以代入:
    fmap (replicate 3) :: f c -> f [c]
    

    那么我们是fmap结束是Just , 它的类型
    Just :: x -> Maybe x
    

    可以以前缀形式重写为
    Just :: (->) x (Maybe x)
    

    或者如果我们真的想要更多的括号
    Just :: ((->) x) (Maybe x)
    

    然后
                       Just :: ((->) x) (Maybe x)
    fmap (replicate 3)      :: f        c         -> f [c]
    

    这意味着
    ((->) x) (Maybe x) ~ f c
    (->) x  ~ f
    Maybe x ~ c
    [c] ~ [Maybe x]
    

    所以代入:
    fmap (replicate 3) :: ((->) x) (Maybe x) -> ((->) x) [Maybe x]
    

    回到中缀符号
    fmap (replicate 3) :: (x -> Maybe x) -> (x -> [Maybe x])
    

    然后申请Just :
    fmap (replicate 3) Just :: x -> [Maybe x]
    

    我想在这里强调Maybe成为 Functor与这个减少无关,唯一的Functor涉及到函数Functor .列表也是 Functor , 但只是因为它出现在 replicate 的类型中并不意味着在这种情况下它很重要。很容易与函数混淆
    fmap (replicate 3) . Just :: a -> Maybe [a]
    

    但由于添加了.,这完全不同。 .

    关于haskell - 为什么 "fmap (replicate 3) Just"的类型为 "a -> [Maybe a]",在 Haskell 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24006068/

    相关文章:

    types - Google 表格支持哪些数据类型?

    c++ - 如何从一个成员类/结构中获取一个类的成员数据?

    haskell - 自动下载haskell项目的依赖项?

    haskell - 返回值的模式匹配

    types - 如何使用 Flux.jl 绘制函数及其梯度/导数

    python - 在 bash 中获取变量类型

    haskell - xmonad自动切换到应用程序

    haskell - 为什么 liftM 不破坏上下文?

    c# - 如何通过将 Func 和 Action 作为参数的函数的两个重载来简化代码?

    c++ - 2种不同的种类,1个仿函数