gpt4 book ai didi

Haskell 函数接受函数或值,然后调用函数或返回值

转载 作者:行者123 更新时间:2023-12-02 12:04:34 25 4
gpt4 key购买 nike

如何在 Haskell 中编写一个类型声明和函数,它接受一个函数(本身不接受参数)一个值。当给定一个函数时,它会调用该函数。当给定一个值时,它返回该值。

[编辑]为了提供更多背景信息,我主要好奇如何在 Haskell 中解决这个问题而不需要一点麻烦: Designing function f(f(n)) == -n

肖恩

最佳答案

I'm mostly curious how to solve this problem in Haskell without bit twiddling: Designing function f(f(n)) == -n

这实际上很容易解决:

when :: (a -> Bool) -> (a -> a) -> a -> a
when p f x = if p x then f x else x

f :: Integer -> Integer
f = (+) <$> when even negate <*> signum

我们如何得出这个?考虑:

f (f n) = (-n) -- (0) - from the interview question

f x = y -- (1) - assumption

f y = (-x) -- (2) - from (0) and (1), f (f x) = (-x)

f (-x) = (-y) -- (3) - from (0) and (2), f (f y) = (-y)

f (-y) = x -- (4) - from (0) and (3), f (f (-x)) = x

现在,如果您看到这些方程的左侧,那么您会注意到有四种情况:

  1. f x
  2. fy
  3. f (-x)
  4. f (-y)

注意函数f的定义域分为正数和负数、x(-x),以及 >y(-y)。假设xy一起构成正数集合以及(-x)(-y) 共同构成负数集合。

正数集合分为两个proper disjoint子集,xy。我们如何将正数集分成两个不相交的真子集?奇数和偶数都是不错的选择。因此,我们假设 x 是正奇数的集合,y 是正偶数的集合。

使用奇数和偶数的另一个优点是,当求反奇数时,奇数仍然是奇数,偶数仍然是偶数。因此,(-x) 是负奇数集合,(-y) 是负偶数集合。

现在,再次考虑这四种情况。请注意,只有当数字为偶数时,符号才会改变:

  1. f x = y(符号不变)。
  2. f y = (-x)(符号更改)。
  3. f (-x) = (-y)(符号不变)。
  4. f (-y) = x(符号更改)。

因此,我们仅在数字为偶数时对它取反(即当偶数取反时)。

接下来,我们需要将奇数转换为偶数,反之亦然。最简单的方法是对数字加一或减一。但是,应注意结果数字不是0。考虑 0 的特殊情况:

f 0    = z    -- (a) - assumption

f z = (-0) -- (b) - from (0) and (a), f (f 0) = (-0)

f (-0) = (-z) -- (c) - from (0) and (b), f (f z) = (-z)

(-0) = 0 -- (d) - reflexivity

f (-0) = f 0 -- (e) - from (d)

(-z) = z -- (f) - from (a) and (c) and (e)

z = 0 -- (g) - from (d) and (f)

f 0 = 0 -- (h) - from (a) and (g)

因此,f n = 0 if and only if n = 0。因此,让我们考虑 01(-1) 的邻居。两者都是奇数。因此,它们并没有被否定。但是,它们确实需要转换为偶数(0 除外)。因此,1 被转换为 2(-1) 被转换为 (-2)

因此,对于奇数,我们只需将数字的符号添加到数字本身即可。

现在,考虑偶数。我们知道:

f 1    = 2    -- (A)

f (-1) = (-2) -- (B)

因此:

f 2    = (-1) -- (C), from (0) and (A), f (f 1) = (-1)

f (-2) = 1 -- (D), from (0) and (B), f (f (-1)) = 1

我们知道偶数总是被求反。因此,2 首先变成 (-2),反之亦然。设原来的偶数为n。因此,首先我们对 n 取反,然后向其添加signum n:

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

因此,对于奇数情况和偶数情况,我们将原始数字的符号添加到偶数否定时。因此,f 定义为:

f :: Integer -> Integer
f = (+) <$> when even negate <*> signum

希望有帮助。

关于Haskell 函数接受函数或值,然后调用函数或返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30251118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com