应用仿函数评估对我来说并不清楚

user6337 2 haskell functional-programming applicative

我正在阅读"了解你是一个很好的Haskell!" 并且我对某个代码块的评估的解释感到磕磕绊绊.我已多次阅读这些解释,并开始怀疑即使是作者也能理解这段代码的作用.

ghci> (+) <$> (+3) <*> (*100) $ 5
508

应用程序函数在某些上下文中将函数应用于某个上下文中的值,以在某些上下文中获得某些结果.我花了几个小时来研究这个代码块,并对这个表达式的评估方式提出了一些解释,但没有一个是令人满意的.我知道(5 + 3)+(5*100)是508,但问题是这个表达式.有没有人对这段代码有明确的解释?

Bergi.. 5

它正在使用应用实例来实现功能.你的代码

(+) <$> (+3) <*> (*100) $ 5

被评估为

( (\a->b->a+b) <$> (\c->c+3) <*> (\d->d*100) ) 5
( (\x -> (\a->b->a+b) ((\c->c+3) x)) <*> (\d->d*100) ) 5
( (\x -> (\a->b->a+b) (x+3)) <*> (\d->d*100) ) 5
( (\x -> b -> (x+3)+b) <*> (\d->d*100) ) 5
( (\x->b->(x+3)+b) <*> (\d->d*100) ) 5
(\y -> ((\x->b->(x+3)+b) y) ((\d->d*100) y)) 5
(\y -> (b->(y+3)+b) (y*100)) 5
(\y -> (y+3)+(y*100)) 5
(5+3)+(5*100)

这里<$>fmap或者只是函数组合.,并且<*>ap如果你知道它是如何表现的单子.


Willem Van O.. 5

让我们先来看看如何fmap(<*>)一个函数的定义:

instance Functor ((->) r) where
    fmap = (.)

instance Applicative ((->) a) where
    pure = const
    (<*>) f g x = f x (g x)
    liftA2 q f g x = q (f x) (g x)

我们要评估的表达方式是:

 (+) <$> (+3) <*> (*100)  $ 5

或者更详细:

((+) <$> (+3)) <*> (*100) $ 5

如果我们因此评估(<$>),这是一个中缀的同义词fmap,我们因此看到它等于:

(+) . (+3)

所以这意味着我们的表达相当于:

((+) . (+3)) <*> (*100) $ 5

接下来我们可以应用顺序应用程序.这里f因此等于(+) . (+3)g(*100).这意味着我们构造一个看起来像这样的函数:

\x -> ((+) . (+3)) x ((*100) x)

我们现在可以简化这个并将其重写为:

\x -> ((+) (x+3)) ((*100) x)

然后将其重写为:

\x -> (+) (x+3) ((*100) x)

因此,我们构建了一个看起来像这样的函数:

\x -> (x+3) + 100 * x

或者更简单:

\x -> 101 * x + 3

如果我们然后计算:

(\x -> 101*x + 3) 5

然后我们当然获得:

101 * 5 + 3

因此:

505 + 3

这是预期的:

508