类型pure
是Applicative f => a -> f a
这样的pure []
有类型Applicative f => f [a]
.您可以f
明确指定不同的应用类型,例如
pure [] :: Maybe [String] //Just [] pure [] :: IO [String] //displays '[]' in ghci pure [] :: [[String]] //[[]]
类型fmap ((:) 2) (pure [])
是(Applicative f, Num a) => f [a]
.由于Ghci在IO monad中运行,它是一个Applicative
,它选择f
是IO
,并显示结果列表[2]
,这是你看到的.
您可以直接指定应用类型以查看不同的结果,例如
fmap ((:) 2) (pure []) :: (Maybe [Int])
是的 Just [2]
在fmap ((:) 2) ([])
,输入列表中没有元素,因此您将获得一个空列表.
类型pure
是Applicative f => a -> f a
这样的pure []
有类型Applicative f => f [a]
.您可以f
明确指定不同的应用类型,例如
pure [] :: Maybe [String] //Just [] pure [] :: IO [String] //displays '[]' in ghci pure [] :: [[String]] //[[]]
类型fmap ((:) 2) (pure [])
是(Applicative f, Num a) => f [a]
.由于Ghci在IO monad中运行,它是一个Applicative
,它选择f
是IO
,并显示结果列表[2]
,这是你看到的.
您可以直接指定应用类型以查看不同的结果,例如
fmap ((:) 2) (pure []) :: (Maybe [Int])
是的 Just [2]
在fmap ((:) 2) ([])
,输入列表中没有元素,因此您将获得一个空列表.
为什么会一样?他们是不同的表达方式.
如果我们只看列表,它可能会简化事情.所以,有空列表[]
.它的类型可以是围绕它的括号,特别是嵌套列表:
前奏> [] :: [[Int]]
[]
但是还有另一个"空嵌套列表":
前奏> [[]] :: [[国际]]
[[]]
这个并不是空的,它只包含空列表.([[],[],[],...]
也是可能的).事实上,如果在列表应用程序中完成,那将是您尝试过的结果:
Prelude Control.Applicative> pure [] :: [[Int]]
[[]]
它肯定与空列表不一样,
前奏> [[]] == []
错误
特别是,
前奏>(长[],长[[]])
(0,1)
并且fmap
在空列表上进行操作永远不会做任何事情,而fmap
ping空包含列表将调用该函数[]
:一个简单的方法来查看这是
Prelude Control.Applicative> fmap undefined []
[]
Prelude Control.Applicative> fmap undefined [[]]
[ * Exception:Prelude.undefined
关于你的试验真正令人困惑的事情是ghci默默使用IO
monad.
还有一个Applicative
实际空虚的子类:
Prelude Control.Applicative>:i Alternative
class Applicative f => Alternative f where
empty :: fa
(<|>):: fa - > fa - > fa
some :: fa - > f [a]
many :: fa - > f [a]
- 在`Control.Applicative'
实例中定义Alternative [] - 在`Control.Applicative'
实例中定义Alternative Maybe - 在`Control.Applicative'中定义