Haskell:理解部分应用?

时间:2012-08-24 12:58:49

标签: haskell currying

我正在阅读有关应用仿函数的LYAH chapter,我似乎不理解以下示例:

ghci> :t fmap (++) (Just "hey")  
fmap (++) (Just "hey") :: Maybe ([Char] -> [Char])

但是当我看到这个时:

ghci> :t (++)
(++) :: [a] -> [a] -> [a]
ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b

我确实理解(* 3)(++“this”)之类的内容如何适合(a - > b)类型,但我只是看不出 [a] - > [a] - > [a] 符合(a - > b)

5 个答案:

答案 0 :(得分:7)

关键是->与右侧相关联,因此像a -> b -> c这样的类型确实是a -> (b -> c)。因此,设置[a] -> [a] -> [a]c -> dc[a]d符合[a] -> [a]。您可以将函数[a] -> [a] -> [a]视为返回类型[a]的结果的2个参数的函数,或者返回类型为[a] -> [a]的结果的1参数的函数。

答案 1 :(得分:6)

要意识到的是b中的a -> b不必是标量 - 它可以是一个函数。

[a] -> [a] -> [a]可以被视为[a] -> ([a] -> [a]),因此b[a] -> [a]

答案 2 :(得分:5)

像往常一样把东西放在一边,

fmap :: Functor f => ( a    ->      b      )   ->      f a        ->   f b
fmap                       (++)                    (Just "hey")   ::   f b
(++) ::               [c]   -> ([c] -> [c])

所以,

a ~ [c]  ,    b ~ ([c] -> [c])  ,    f ~ Maybe  ,    a ~ [Char]  ,   c ~ Char

f b ~ Maybe b ~ Maybe ([c] -> [c]) ~  Maybe ([Char] -> [Char])

这里不涉及任何想法。类型的统一是一个机械过程。


要回答您的具体问题(转述),[c] -> [c] -> [c]如何与a -> b”匹配,请点击此处:

  • 在签名类型中省略括号是邪恶的(在向新手教授Haskell时)
  • 在Haskell中,没有二进制函数。每个功能都是一元的。
  • 因此(正如其他人已提及的那样),类型签名中的箭头与右侧相关

答案 3 :(得分:4)

真的很简单:-)。让我添加一个简单的括号:

[a]->[a]->[a][a]->([a]->[a])

类似

因此,a->b[a]和b替换为[a]->[a],从而适合string->string。你给一个字符串给++,你得到一个类型为fmap (++) (Just "hey")的函数作为回报

Maybe ([Char] -> [Char])是一个monad,它可以保存一个函数,该函数将字符串“hey”作为前缀添加到另一个字符串。它确实属于{{1}}

类型

答案 4 :(得分:4)

考虑Maybe类型的fmap定义。

fmap f (Just x) = Just (f x)

您的示例看起来像

fmap (++) (Just "Hey") = Just ("Hey" ++) :: Maybe ([Char] -> [Char])

正如fmap应该的那样,你只需在Maybe容器中解除(++)函数 将其应用于内容。