首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从上下文中获取价值还是把它们置之不理?

从上下文中获取价值还是把它们置之不理?
EN

Stack Overflow用户
提问于 2018-08-01 06:02:57
回答 1查看 132关注 0票数 0

假设下面是代码。是否有更快的方法从findSerial中获取上下文值,而不是编写像outOfContext这样的函数?根本的问题是:一个人通常会在上下文中使用函子、应用程序、Monoids和Monads来完成任务,还是把它从上下文中去掉并应用通常的非上下文计算方法更好。简单地说:我不想完全错误地学习Haskell,因为它需要足够的时间。

代码语言:javascript
复制
import qualified Data.Map as Map
type SerialNumber = (String, Int)
serialList :: Map.Map String SerialNumber
serialList = Map.fromList [("belt drive",("BD",0001))
                          ,("chain drive",("CD",0002))
                          ,("drive pulley",("DP",0003))
                          ,("drive sprocket",("DS",0004))
                          ]
findSerial :: Ord k => k -> Map.Map k a -> Maybe a
findSerial input = Map.lookup input
outOfContext (Just (a, b)) = (a, b)
EN

回答 1

Stack Overflow用户

发布于 2018-08-01 06:23:31

假设我正确理解了它,我认为您的问题本质上归结为“编写和使用部分函数在Haskell中是惯用的吗?”(这是outOfContext函数,因为它只是内置的部分函数fromJust的一种专门形式)。这个问题的答案是一个响亮的no。尽可能避免部分函数,使用它们的代码通常可以重构为不使用它们的代码。

避免部分功能的原因是它们自愿地损害了类型系统的有效性。在Haskell中,当一个函数具有X -> Y类型时,通常假定提供给它一个X实际上会产生一个Y,并且它不会完全执行其他事情(即崩溃)。如果您的函数并不总是成功,那么通过编写X -> Maybe Y来反映该类型的信息会迫使调用方以某种方式处理Nothing情况,并且它可以直接处理它,或者将故障进一步推迟到调用方(也可以生成一个Maybe)。这很好,因为这意味着打字机程序不会在运行时崩溃。程序可能仍然有逻辑错误,但是即使在运行程序之前就知道它不会爆炸,这仍然是相当不错的。

部分函数将此保证抛出窗口。如果函数的先决条件被意外违反,任何使用部分函数的程序都会在运行时崩溃,而且由于这些先决条件没有反映在类型系统中,所以编译器不能静态地执行这些先决条件。在编写程序时,程序可能在逻辑上是正确的,但不强制使用类型系统的正确性,进一步的修改、扩展或重构很容易错误地引入错误。

例如,程序员可能会编写表达式。

代码语言:javascript
复制
if isJust n then fromJust n else 0

这肯定不会在运行时崩溃,因为fromJust的前提条件总是在调用之前进行检查。但是,类型系统不能强制这样做,进一步的重构可能会交换if的分支,或者它可能会将fromJust n完全移动到程序的另一个部分,并且意外地忽略了isJust检查。该程序仍将编译,但在运行时可能会失败。

相反,如果程序员避免使用与case的显式模式匹配或maybefromMaybe之类的总函数来避免部分函数,则可以将上面的复杂条件替换为以下内容

代码语言:javascript
复制
fromMaybe 0 n

这不仅更加清晰,而且确保任何意外的误用都会使打字机无法正常运行,而且潜在的错误将被更早地检测出来。

关于类型系统如何成为一个强大的盟友的一些具体例子,如果您只坚持全面的功能,以及一些很好的食物来思考如何将您的域的类型安全编码到Haskell的类型系统中,我强烈建议阅读Matt的精彩博客文章安全背四型,它更深入地探讨了这些想法。此外,它还强调了如何使用Maybe作为失败的全捕获表示是很尴尬的,它还展示了如何使用类型系统来执行先决条件,以避免在整个系统中传播Maybe

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51626308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档