functional programming - Haskell function that accepts function or value, then calls function or returns value -
how can write type declaration , function in haskell takes either function (that takes no arguments) or value. when given function calls function. when given value returns value.
[edit] give more context, i'm curious how solve problem in haskell without bit twiddling: designing function f(f(n)) == -n
sean
i'm curious how solve problem in haskell without bit twiddling: designing function f(f(n)) == -n
that's quite easy solve:
when :: (a -> bool) -> (a -> a) -> -> when p f x = if p x f x else x f :: integer -> integer f = (+) <$> when negate <*> signum how derive this? consider:
f (f n) = (-n) -- (0) - interview question f x = y -- (1) - assumption f y = (-x) -- (2) - (0) , (1), f (f x) = (-x) f (-x) = (-y) -- (3) - (0) , (2), f (f y) = (-y) f (-y) = x -- (4) - (0) , (3), f (f (-x)) = x now, if see left hand sides of these equations you'll notice there 4 cases:
f x.f y.f (-x).f (-y).
notice domain of function f divided positive , negative numbers, x , (-x), , y , (-y). let's assume x , y form set of positive numbers , (-x) , (-y) form set of negative numbers.
the set of positive numbers divided 2 proper disjoint subsets, x , y. how divide set of positive numbers 2 proper disjoint subsets? odd , numbers candidate. hence, let's assume x set of positive odd numbers , y set of positive numbers.
another advantage of using odd , numbers when negated odd numbers remain odd , numbers remain even. hence, (-x) set of negative odd numbers , (-y) set of negative numbers.
now, consider 4 cases again. notice sign changes when number even:
f x = y(sign not change).f y = (-x)(sign changes).f (-x) = (-y)(sign not change).f (-y) = x(sign changes).
hence, negate number when (i.e. when negate).
next, need convert odd numbers numbers , vice versa. easiest way add or subtract 1 number. however, care should taken resulting number not 0. consider special case of 0:
f 0 = z -- (a) - assumption f z = (-0) -- (b) - (0) , (a), f (f 0) = (-0) f (-0) = (-z) -- (c) - (0) , (b), f (f z) = (-z) (-0) = 0 -- (d) - reflexivity f (-0) = f 0 -- (e) - (d) (-z) = z -- (f) - (a) , (c) , (e) z = 0 -- (g) - (d) , (f) f 0 = 0 -- (h) - (a) , (g) hence, f n = 0 if , if n = 0. let's consider neighbors of 0, 1 , (-1). both of them odd numbers. hence, not negated. however, need converted number (except 0). hence, 1 converted 2 , (-1) converted (-2).
thus, odd numbers add sign of number number itself.
now, consider numbers. know:
f 1 = 2 -- (a) f (-1) = (-2) -- (b) therefore:
f 2 = (-1) -- (c), (0) , (a), f (f 1) = (-1) f (-2) = 1 -- (d), (0) , (b), f (f (-1)) = 1 we know numbers negated. hence, 2 first becomes (-2) , vice versa. let original number n. hence, first negate n , add signum n it:
evenf n = negate n + signum n evenf 2 = negate 2 + signum 2 = (-2) + 1 = (-1) evenf (-2) = negate (-2) + signum (-2) = 2 + (-1) = 1 evenf 0 = negate 0 + signum 0 = 0 + 0 = 0 thus, both odd case , case add sign of original number when negate. therefore, f defined as:
f :: integer -> integer f = (+) <$> when negate <*> signum hope helps.
Comments
Post a Comment