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