如何返回Haskell中的中间数字

如何返回Haskell中的中间数字,haskell,int,guard,Haskell,Int,Guard,我有以下函数开头,不确定如何返回中间数(即既不是最大值也不是最小值的数): 我建议您将函数分为两个步骤:首先,对三个数字进行排序。然后,以中间元素为例。对于第一步,也要考虑是否可以一步一步地进行;每一步都会使它离完全排序更近一点,然后尾部递归回来使它更接近。中间数字大于其中一个数字,但小于另一个数字。只有一个中间数字。解决这个问题的最机械的方法是开始 middleNumber a b c | a < b && a > c = a 中间编号a b c |ac=

我有以下函数开头,不确定如何返回中间数(即既不是最大值也不是最小值的数):


我建议您将函数分为两个步骤:首先,对三个数字进行排序。然后,以中间元素为例。对于第一步,也要考虑是否可以一步一步地进行;每一步都会使它离完全排序更近一点,然后尾部递归回来使它更接近。

中间数字大于其中一个数字,但小于另一个数字。只有一个中间数字。解决这个问题的最机械的方法是开始

middleNumber a b c
    | a < b && a > c = a
中间编号a b c
|ac=a
通过小于
b
但大于
c
检查
a
是否为中间数

现在,如果
a
是中间数,但它实际上大于
b
,小于
c
,该怎么办?还有一个警卫。如果
b
是中间的数字怎么办?还有两个警卫。如果
c
是中间的数字怎么办?另外还有两名警卫,总共负责6个不同的案件

(顺便说一句,表达式
|ac=a
被称为卫兵。如果你还不清楚卫兵是什么,我建议你)


当然,有更好的方法来编写函数,但是为了便于理解,最好能够手动和系统地分解所有可能的情况,并确定在每种情况下要做什么。这是一本学习如何以这种方式系统化的好书。

鲁布·戈德堡的必修答案:

import Control.Applicative

middleNumber a b c = sum $ [sum, negate.minimum, negate.maximum] <*> [[a,b,c]]

我相信我们可以将其转换为箭头语法以进一步混淆,但我将此任务留给感兴趣的读者。

我使用了一种快速暴力方法,但这肯定不是最佳解决方案

import Data.List
middleNum :: Int -> Int -> Int -> Int
middleNum a b c = (\[_,m,_] -> m) $ sort $ a:b:c:[]

显然,这是一个糟糕的想法,因为它明确地依赖于列表中有3项,但它确实起到了作用

根据Dan Burton关于警卫的回答,我对a、b、c三种情况分别进行了评估。然而,当两个数字相等时会发生什么?那么中间的数字应该是重复的数字之一

middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
    | (a > b && a < c) || (a > c && a < b) = a
    | (b > a && b < c) || (b > c && b < a) = b
    | (c > a && c < b) || (c > b && c < a) = c
    | otherwise = if a == b then a else c
middleNumber::Int->Int->Int->Int
中间号码a b c
|(a>b&&ac&&aa&bc&ba&cb&c
您可以利用防护装置和
where
以简单的方式获得相同的结果:

middleNumber::Int->Int->Int->Int
中间数x y z
|a==x=最大y z
|a==y=max x z
|a==z=max x y
哪里
a=最大值x$最大值y z
如果您无法访问内置的
max
。你可以很容易地写你自己的

max'::Int->Int->Int
max'x y
|x>y=x
|否则=y

谢谢,我来试试:)导入数据。列表;中间编号a b c=(排序[a,b,c])!!1
让l=[a,b,c]在delete中(最小l)。删除(最大l)$l
..:-)另一个:
middleNumber a b c=minimum[max a b,max a c,max b c]
(逆方向也可以)@all:Nice!我认为到处玩是一个让人对语言有更好感觉的好方法,而教科书上的答案只是无聊而已。
import Data.List
middleNum :: Int -> Int -> Int -> Int
middleNum a b c = (\[_,m,_] -> m) $ sort $ a:b:c:[]
middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
    | (a > b && a < c) || (a > c && a < b) = a
    | (b > a && b < c) || (b > c && b < a) = b
    | (c > a && c < b) || (c > b && c < a) = c
    | otherwise = if a == b then a else c