是否可以在Haskell中执行嵌套的if语句?

是否可以在Haskell中执行嵌套的if语句?,haskell,if-statement,Haskell,If Statement,我试图对列表中的3个元素进行排序。但我在将其转换为haskell时遇到了困难。是否可以在haskell中执行嵌套的if语句?我一直在尝试模式匹配,但这会花费我很多时间 if (x < y) { if (z < x) swap(x,z); } else { if (y < z) swap(x,y); else swap(x,z); } if(z<y) swap(y,z); if(x排序)->[a]->[a] sort3 cmp[a,b,c]=如果cmp

我试图对列表中的3个元素进行排序。但我在将其转换为haskell时遇到了困难。是否可以在haskell中执行嵌套的if语句?我一直在尝试模式匹配,但这会花费我很多时间

if (x < y) {
    if (z < x) swap(x,z);
} else {
   if (y < z) swap(x,y);
else swap(x,z);
} 
  if(z<y) swap(y,z);
if(x排序
intCMP a b | a==b=EQ
|a(a->a->排序)->[a]->[a]
sort3 cmp[a,b,c]=如果cmp a b==LT则
如果cmp a c==Lt,则
如果cmp b c==LT,则
[甲、乙、丙]
其他的
[甲,丙,乙]
其他的
[c、a、b]
否则,如果cmp b c==LT,则
如果cmp a c==LT,则
[b、a、c]
其他的
[b、c、a]
其他的
[c、b、a]

这个技巧是,在Haskell
中,if
不是一个语句,而是一个表达式。它从一个分支返回一个值,而不是在那里执行代码。事实上,
if
可能只是函数的语法糖
if::Bool->a->a
(当然,这样的函数不可能存在,因为如果
是一个关键字,那么
就是一个关键词;但是,如果它的名称不同,我们可以轻松地实现这样一个函数)

所以,是的,嵌套的
if
语句是可能的,就像任何表达式一样,如

max x y z = if x < y then (if y < z then z else y) else (if x < z then z else x)

正如lisyarus所说,您可以这样做。但是,如果Haskell中的
通常有点笨拙;通常,模式匹配是一个更好的选择-这可以避免布尔瓶颈,并允许您直接解构有意义的值。在您的情况下,最明显的事情是将丑陋的
==LT
检查替换为
大小写
表达式:

sort3 cmp [a,b,c] = case cmp a b of
      LT -> case cmp a c of
         LT -> ...
尽管如此,由于您始终检查所有三个,因此实际上不需要嵌套检查;您不妨将它们全部检查一次:

sort3 cmp [a,b,c] = case (cmp a b, cmp a c, cmp b c) of
       (GT, _ , GT) -> [c,b,a]
       (GT, LT, _ ) -> [b,a,c]
       (_ , LT, GT) -> [a,c,b]
       (_ , GT, _ ) -> [c,a,b]
       (GT, _ , _ ) -> [b,c,a]
       _            -> [a,b,c]

对于三个元素来说,这并不重要,但一旦你达到四个元素,你就有了交换的概念,尽管我不同意你的交换机制。你可以通过给计算的每个阶段赋予它自己的功能来做到这一点

data Triple a = Triple a a a
sort3, sort3', sort3''
  :: Ord a => Triple a -> Triple a

sort3 t@(Triple x y z)
  | x <= y = sort3' t
  | otherwise = sort3' (Triple y x z)

-- Precondition : the first two elements are in order
sort3' t@(Triple x y z)
  | x <= z = sort3'' t
  | otherwise = Triple z x y

-- Precondition: The smallest element is first
sort3'' t@(Triple x y z)
  | y <= z = t
  | otherwise = Triple x z y
data Triple a=Triple a
sort3,sort3',sort3“
::Ord a=>Triple a->Triple a
sort3 t@(三重x y z)

|x“是”此外,那些嵌套的if语句可以展平。展平是什么意思?Haskell实际上没有if语句。它有if表达式。是什么让你怀疑它们的嵌套能力?尝试时出现了什么问题?除了一个小的打字错误(
Lt
for
Lt
)当我尝试时,该代码运行得很好。另请参见“我不明白你想说什么”作为
if
函数的语法糖。当然,没有这样的函数,这是不可能的,因为
if
是一个保留标记。你可能会说它是
Data.Bool.Bool::a->a->Bool->a
,虽然参数的顺序当然不同。@amalloy谢谢,我会更改措辞。如果这听起来让人困惑,我很抱歉。我的意思是,
if
不是什么神奇的东西,可以被认为是一个函数
if::Bool->a->a->a
。当然,没有,也不可能有这样的函数没错。不过,我们可以用不同的名称来命名它,在函数中有效地实现
if
操作符。
sort3 cmp [a,b,c] = case (cmp a b, cmp a c, cmp b c) of
       (GT, _ , GT) -> [c,b,a]
       (GT, LT, _ ) -> [b,a,c]
       (_ , LT, GT) -> [a,c,b]
       (_ , GT, _ ) -> [c,a,b]
       (GT, _ , _ ) -> [b,c,a]
       _            -> [a,b,c]
data Triple a = Triple a a a
sort3, sort3', sort3''
  :: Ord a => Triple a -> Triple a

sort3 t@(Triple x y z)
  | x <= y = sort3' t
  | otherwise = sort3' (Triple y x z)

-- Precondition : the first two elements are in order
sort3' t@(Triple x y z)
  | x <= z = sort3'' t
  | otherwise = Triple z x y

-- Precondition: The smallest element is first
sort3'' t@(Triple x y z)
  | y <= z = t
  | otherwise = Triple x z y