在Haskell中,类Functor
声明为:
class Functor f where
fmap :: (a -> b) -> f a -> f b
类型变量a
和b
是函数类型,还是必须是非函数类型?
如果它们可以是函数类型,那么在使Functor
可以应用于任意数量的函数方面,类Applicative
是否与类fmap
变得有效相同?论据?根据赫顿的在Haskell中编程说:
Functor将
fmap
的概念映射到结构的每个元素上。应用程序将此思想概括为允许映射具有任意数量参数的fmap
映射函数,而不是局限于具有单个参数的函数。
在适用范围内:
fmap0 :: a -> f a fmap0 = pure fmap1 :: (a -> b) -> f a -> f b fmap1 g x = pure g <*> x fmap2 :: (a -> b -> c) -> f a -> f b -> f c fmap2 g x y = pure g <*> x <*> y fmap3 :: (a -> b -> c -> d) -> f a -> f b -> f c -> f d fmap3 g x y z = pure g <*> x <*> y <*> z
类Applicative
声明为:
class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b
谢谢。
答案 0 :(得分:11)
可以将变量
a
和b
键入为函数类型
–是的,肯定。
不是类
Functor
与类Applicative
一样有效
不,绝对不是。如果将函数类型插入a
签名的b
或fmap
中,则会得到类似
fmap :: ((x -> y) -> b) -> f (x -> y) -> f b
或
fmap :: (a -> p -> q) -> f a -> f (p -> q)
但至关重要的是,fmap
总是正好取一个f _
包装值,而恰好吐出一个这样的值。同时,Applicative
允许您接受任意数量的个包装的值,只要您为其提供了一个处理包含的值的功能。
答案 1 :(得分:11)
function emailCurrentSheetAsPDF() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var shts=ss.getSheets();
for(var i=0;i<shts.length;i++) {
if(shts[i]!=sh) {
shts[i].hideSheet();
}
}
var fldr=DriveApp.getRootFolder();
var file=fldr.createFile(ss.getBlob().getAs('application/pdf'));
GmailApp.sendEmail("bighillhelitack@gmail.com", "F-106", "Aircraft Dispatch",{attachments:[file]});
file.setTrashed('true');
}
和a
可以是函数类型。它们可以是任何类型。实际上,有效的b
必须允许它们为任何类型。
要回答您的Functor
问题,请尝试一下。
Applicative
好的,太好了!现在,我可以将fmap :: (a -> b -> c) -> f a -> f (b -> c)
转换为f a
。但是...那又怎样?我无法将f (b -> c)
应用于自变量。这不是一个功能;这是我的函子类型的值。如果只有一个具有此签名的功能...
f (b -> c)
但是那确实看起来很像
superFmap :: f (b -> c) -> f b -> f c
是(<*>) :: f (b -> c) -> f b -> f c
成员的。因此,我们需要Applicative
才能应用此次要结果。
其他答案是正确的。由于类似的原因,我们也无法实现Applicative
。但是需要特别注意的是,我们一般甚至无法获得pure
,因为如果可以的话,这意味着每个(<*>)
都是Apply
,当然也并非如此。
答案 2 :(得分:4)
类型变量
a
和b
是函数类型,还是必须是非函数类型?
a
和b
可以是 any 类型,因此函数类型也是如此。
例如,我们可以使用:
fmap (+) [1,4,2,5]
(+)
的类型为:
fmap :: Functor f => (a -> b ) -> f a -> f b
(+) :: Num c => c -> (c -> c)
因此,b ~ c -> c
和b
是一个函数。
其中a
是一个函数的示例是:
fmap ($ 2) [ (1+), (2*), (3-) ]
这里有类型:
fmap :: Functor f => (a -> b) -> f a -> f b
($ 3) :: Num c => (c -> d) -> d
因此,a ~ (c -> d)
在这里,因此我们在此处将3
应用于列表中的所有功能。
请注意,我们没有在此处添加额外的fmap
定义(如fmap1
,fmap2
等)。事实是a
可以用类型c -> d
等代替。
如果它们可以是函数类型,那不是类
Functor
与类Applicative
一样有效。
否,因为例如没有说可以为给定的pure
实现Functor
。想象一下,例如,您将数据类型设置为:
type Owner = String
data Owned a = Owned Owner a
然后可以将Owned
实现为Functor
的实例:
instance Functor Owned where
fmap f (Owned o x) = Owned o (f x)
但是无法实现pure :: a -> Owned a
:为什么要成为对象的所有者?