1

我试图了解 Haskell 是如何评估pp1 [1,2,3,4][(1,2),(2,3),(3,4)]这里的:

1. xnull f [] = []
2. xnull f xs = f xs
3. (/:/) f g x = (f x) (g x)
4. pp1 = zip /:/ xnull tail

我是这样开始的:

a)  pp1 [1,2,3,4] = (zip /:/ xnull tail) [1,2,3,4]  -- (rule 4).
b)  (zip /:/ xnull tail) [1,2,3,4] 
       = (zip (xnull [1,2,3,4]) (tail) [1,2,3,4])   -- (rule 3)
c)  -- I'm not sure how to continue because xnull receives a function 
    -- and a param, and in this case it only receives a param.

有什么帮助吗?

4

3 回答 3

4

继续扩大:

pp1 [1, 2, 3, 4] = zip /:/ xnull tail $ [1, 2, 3, 4]
                 -- inline (/:/) f g x = f x (g x)
                 --  f = zip, g = xnull tail, x = [1, 2, 3, 4]
                 -- therefore: 
                 = zip [1, 2, 3, 4] (xnull tail $ [1, 2, 3, 4])
                 -- inline the definition of xnull and note that the argument is not null
                 -- so we just want f x, or tail [1, 2, 3, 4]
                 = zip [1, 2, 3, 4] (tail [1, 2, 3, 4])
                 -- evaluate tail
                 = zip [1, 2, 3, 4] [2, 3, 4]
                 -- evaluate zip
                 = [(1, 2), (2, 3), (3, 4)]

运营商负责人很重要。您没有指定 的关联性,(/:/)因此它默认为相对较弱。因此,(xnull tail)约束比 更紧(/:/)

另外,作为旁注,(/:/)标准库中已经存在(<*>)from Control.Applicative。它足够通用,因此可能很难看到,但是Applicativefor 的实例Reader(或者可能更好地理解为 function Applicative)提供了这个确切的实例。它也被称为apfrom Control.Monad

zip <*> tail :: [b] -> [(b, b)]
zip <*> tail $ [1, 2, 3, 4] = [(1, 2), (2, 3), (3, 4)]
于 2014-04-25T17:47:35.243 回答
4

这是错误的

b) (zip /:/ xnull tail) [1,2,3,4] = (zip (xnull [1,2,3,4]) (tail) [1,2,3,4]) (rule 3)

因为它应该是

b) (zip /:/ xnull tail) [1,2,3,4] = (zip [1,2,3,4] (xnull tail [1,2,3,4])) (rule 3)

错误在于阅读zip /:/ xnull tail为 in(zip /:/ xnull) tail而不是zip /:/ (xnull tail).

于 2014-04-25T17:43:08.163 回答
0

我知道这已经有点老了。但无论如何,这是我的看法..

有助于查看定义

pp1 =  zip  /:/  xnull tail
    = (zip) /:/ (xnull tail)
    = (/:/) zip (xnull tail)

请注意括号周围的(xnull tail)指示功能应用程序具有更高的中缀运算符优先级。

现在 的定义(/:/)是返回另一个函数q,该函数将接受一个参数x,并返回应用该函数的结果,该函数通过将其第一个参数部分应用于r应用其第二个参数返回的内容而返回s

f将需要能够接受至少 2 个参数,而g只需要至少 1 个。

(/:/) f g = q 
            where
            q x = r s
                  where
                  r = f x
                  s = g x

请注意,rf x,所以q xf x s

写起来会更清楚

f /:/ g = (\x -> f x (g x))

现在给出

pp1 = zip /:/ xnull tail 

我们可以扩展到

pp1 = q
      where
      q x = r s
            where
            r = zip x
            s = xnull tail x

或者

pp1 = (\x -> zip x $ xnull tail x)

其余的只是替换x[1,2,3,4]进行评估。

于 2014-09-20T14:39:33.463 回答