为什么 Maybe 类型将其值包装在列表中?

Why does the Maybe type wrap its value in a list?

我正在阅读 learnyouahaskell,一本很棒的书,我正在阅读有关类型类的章节。这是问题。在 GHCi 中,当我输入

fmap (++ "String to be appended to") ("I am a basic string, not a type constructor")

我收到错误

Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [[Char]]
  Actual type: [Char]
In the second argument of ‘fmap’, namely
  ‘("I am a basic string, not a type constructor")’

我明白为什么我会收到这个错误(因为仿函数需要一个类型构造函数,其值类似于 Just "I am a value being passed to the Maybe type constructor" 但我不明白为什么错误读取预期类型 [[Char]] 是也许键入实际上将值包装在列表中?有什么关系?

List [] 也是一个函子。 GHC 将 fmap 统一到列表中,并从第一个参数推断出它的类型是 fmap :: (String -> String) -> [String] -> String:

λ Prelude > :t (fmap :: (String -> String) -> [String] -> [String]) (++ "String to be appended to")  ("I am a basic string, not a type constructor")

<interactive>:1:88:
    Couldn't match type ‘Char’ with ‘[Char]’
    Expected type: [String]
    Actual type: [Char]

但您可能希望 fmap 专用于 fmap :: (String -> String) -> Maybe String -> Maybe String,这会给出不同的错误消息:

λ Prelude > (fmap :: (String -> String) -> Maybe String -> Maybe String) (++ "String to be appended to")  ("I am a basic string, not a type constructor")

<interactive>:11:96:
    Couldn't match expected type ‘Maybe String’
                with actual type ‘[Char]’
    In the second argument of ‘fmap ::
                                 (String -> String) -> Maybe String -> Maybe String’, namely
      ‘("I am a basic string, not a type constructor")’

有时 GHC 无法理解我们的意图,并找到我们错误的 "wrong" 原因。

如果您只需添加 Just:

,您的代码就可以正常工作
fmap (++ "xyz") (Just "another string")

结果:Just "another stringxyz"