繁体   English   中英

如何修改这个 Haskell function 所以我不必导入 Data.Bool 并且只使用前奏 function?

[英]How do I modify this Haskell function so I don't have to import Data.Bool and only use prelude function?

我想在下面构建 function,只使用 function 中内置的前奏而不导入 Data.Bool。 I want to replace bool function to something else so I don't have to import Data.Bool and function prints same output as below function. 我该怎么做才能返回相同的 output?

increment :: [Bool] -> [Bool]
increment x = case x of
  [] -> [True]
  (y : ys) -> not y : bool id increment y ys

Data.Bool 中的boolif语句的作用完全相同,因此它可以作为一种实现方式:

    bool x y b = if b then y else x

@dfeuer 在评论中建议您应该丢弃此代码,因为它很恶心,而是尝试自己编写。 如果您是首先编写代码的人并且看不出它为什么令人作呕,那么这可能会让您感到痛苦,所以请允许我详细说明。

事实上,“恶心”这个词太强了。 但是,代码过于复杂且难以理解。 一个更直接的实现使用 function 参数上的模式匹配来完成所有处理:

increment :: [Bool] -> [Bool]
increment [] = [True]
increment (False : rest) = True  : rest
increment (True  : rest) = False : increment rest

对于大多数人来说,这段代码更容易阅读,因为所有的决策逻辑都处于相同的“级别”并且以相同的方式实现——通过检查定义左侧的三个模式,您可以确切地看到如何三、互斥案件一目了然。

相反,原始代码要求读者考虑针对空与非空列表的模式匹配、“非”计算对第一个 boolean 的影响、基于相同 boolean 的bool调用以及应用function id或 boolean 列表的 rest 上的递归increment 对于任何给定的输入,您需要考虑所有四个概念上不同的处理步骤,以了解 function 正在做什么,最后,您可能仍然不确定哪些步骤是由输入的哪些方面触发的。

现在,理想情况下,带有-O2的 GHC 将在内部将这两个版本编译为完全相同的代码。 几乎可以。 但是,事实证明,由于一个明显的优化错误,原始代码最终的效率略低于这个重写版本,因为它不必要地检查y == True两次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM