haskell - fmap 在 Nothing 上的 2-arity 函数应该返回 Nothing?
问题描述
来自ghcMaybe
的来源:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
当fmap
应用于时Nothing
,它应该返回Nothing
。
例如,在 ghci (v8.2.2) 中运行:
Prelude> fmap (+1) Nothing
Nothing
但是,当我应用一个元数为 2 的函数时:
Prelude> fmap (++) Nothing
<interactive>:11:1: error:
• No instance for (Show ([a0] -> [a0]))
arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
• In a stmt of an interactive GHCi command: print it
事实上,结果似乎是Nothing
:
Prelude> import Data.Maybe
Prelude Data.Maybe> isNothing $ fmap (++) Nothing
True
我的问题是,fmap (++) Nothing
真的回来了Nothing
吗?
解决方案
是的。让我们看一下类型:
fmap :: Functor f => (a -> b) -> f a -> f b
(++) :: [a] -> [a] -> [a]
所以,
fmap (++) :: Functor f => f [a] -> f ([a] -> [a])
fmap
采用 1-arity 函数。然而,在 Haskell 中,2-arity 函数只是一个 1-arity 函数,它返回另一个 1-arity 函数:
([a] -> [a] -> [a]) ~ ([a] -> ([a] -> [a]))
所以你的fmap (++) :: Maybe [a] -> Maybe ([a] -> [a])
如果你传递Nothing
给它,它会返回Nothing
. 如果您通过Just "foo"
(例如),它会返回Just
一个函数,该函数接受一个字符串并在"foo"
其前面添加:
Prelude> Just f = fmap (++) $ Just "foo"
Prelude> f "bar"
"foobar"
您收到错误的原因是因为 GHCi 尝试打印输出,这意味着输出必须实现Show
类型类。它试图做的show
是Nothing :: Maybe ([a] -> [a])
. 类型系统不知道它只需要 print Nothing
,它只知道它不能show
是[a] -> [a]
. 所以它打印错误。
推荐阅读
- sql-server - 从 VB.NET 错误地插入 SQL 日期时间
- sql - 如何根据字段标题拆分列
- java - 修复 Java newInstance() 已弃用
- c# - ItextSharp 仅从我的 pdf 中检索标题文本
- batch-file - 如何将批处理脚本转换为注册表上下文菜单文件 REG_MULTI_SZ
- sql-server - 双向同步 2 SQL Server 数据库
- python - 实参的复函数
- linux - 如何在构建 Xenomai 时修复错误“'recipe for target'doc/automake-1.14.1' failed”
- bash - 如何将多个变量连接到命令并执行它?
- excel - VBA:如何在单元格中插入 VLookup 公式(而不是值)?