How are Haskell guards rated?

I am doing 99 Haskell problems, and in one of the solutions I came across the following code:

pack' [] = []
pack' [x] = [[x]]
pack' (x:xs)
    | x == head  h_p_xs = (x:h_p_xs):t_p_hs
    | otherwise         = [x]:p_xs
    where p_xs@(h_p_xs:t_p_hs) = pack' xs

I am wondering when the package will be called in the first guard, and if it is a common template in Haskell code, to refer to the head and tail of the list returned by the function call. Are there several calls for the package at any recursion level and is this a quick fix?

+4
source share
3 answers

I wonder when the package will be called into the first guard

A guard x == head h_p_xsforces a evaluate h_p_xs, which calls a recursive call.

and if this is a common template in Haskell code to refer to the head and tail list returned from the function call.

, . case pack' xs of ... let ... = pack' xs in ....

, let where , h_p_xs:t_p_xs, , . , emlty.

'

, Haskell , , , . , , .

, , - .

, , (!)

...
where p_xs = h_p_xs:t_p_hs
      h_p_xs = head (pack' xs)
      t_p_xs = tail (pack' xs)

, .

?

. , .

+2

pack ', , Data.List.group. . , pack '[1,1,3,2,2] [[1,1], [3], [2,2]].

- haskell. , ,

h_p_xs:t_p_hs = pack' hs

, hs . , h_p_xs , t_p_hs . LHS, RHS ​​ , ( ) Haskell. p_xs RHS (@pattern). , , Haskell.

. , , , .

pack ', - O (n) . .

+2

, . , , -

p_xs@(  (h_p_x : h_p_xs)  : t_p_hs) = pack' xs

p_xs@( h_p_xs : t_p_hs ) = pack' xs

, h_p_x. :

| x == head  h_p_xs = (x : h_p_x: h_p_xs):t_p_hs

So you see that using the operator :here is just cluttering up the code by adding useless objects. As for the number of recursions, I see here only one recursive call at each level, so this is basically linear runtime and therefore efficient.

+1
source

Source: https://habr.com/ru/post/1568663/


All Articles