在类Functor的声明中,类型变量可以是函数类型吗?

时间:2019-07-17 23:02:29

标签: haskell functor applicative

在Haskell中,类Functor声明为:

class   Functor f   where
fmap    ::  (a  ->  b)  ->  f   a   ->  f   b

类型变量ab是函数类型,还是必须是非函数类型?

如果它们可以是函数类型,那么在使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

谢谢。

3 个答案:

答案 0 :(得分:11)

  

可以将变量ab键入为函数类型

–是的,肯定。

  

不是类Functor与类Applicative一样有效

不,绝对不是。如果将函数类型插入a签名的bfmap中,则会得到类似

的信息
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)

  

类型变量ab是函数类型,还是必须是非函数类型?

ab可以是 any 类型,因此函数类型也是如此。

例如,我们可以使用:

fmap (+) [1,4,2,5]

(+)的类型为:

fmap :: Functor f => (a -> b       ) -> f a -> f b
(+)  :: Num c =>      c -> (c -> c)

因此,b ~ c -> cb是一个函数。

其中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定义(如fmap1fmap2等)。事实是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:为什么要成为对象的所有者?