使用Haskell的类型替换断言语句或者用其他语言进行检查 [英] Using Haskell's types to replace assert statements or if checks in other languages

查看:113
本文介绍了使用Haskell的类型替换断言语句或者用其他语言进行检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,如果问题很简单,我对Haskell仍然很陌生。比方说,我有一个函数只能处理两个数字(黄金配给(1.618)),我如何定义 myfun xy 的类型只取得黄金比率数字。如果我在程序中调用没有黄金比例数字的myfun会发生什么(编译错误?)?如果没有黄金比例数字的调用通过用户输入在运行时产生,会发生什么情况?

您可能需要一个 ADT 只能用黄金比例数字构造,然后写myfun才能接受该数据类型。



我假设Integer是一个基类型,但您可以使用其他类型(例如Double或Float),甚至可以是多态。

1)制作ADT

  module Golden(Gold,getGold,buildGold)其中

data Gold = G整数整数

getGold :: Gold - > (整数,整数)
getGold(G x y)=(x,y)

buildGold :: Integer - >整数 - >也许黄金
buildGold x y
| isGolden x y = Just(G x y)
|否则= Nothing

注意这个模块导出 Gold 类型但不是构造函数(即不是 G )。因此,获取 Gold 类型值的唯一方法是执行运行时检查的 buildGold - 但仅限于一 - 所以黄金的价值可以被使用,并被假定为所有消费者的黄金比例而不用检查。

<2>使用ADT构建 myfun

  myfun :: Gold  - > ??? 
myfun g = expr
其中(x,y)= getGold g

现在,如果您尝试使用非黄金数字(非 Gold 类型的值)调用 myfun ,那么您将得到一个编译时错误。

重新获得
建立黄金数字 buildGold 函数必须被使用,其中强制检查数字。



注意什么时候检查!您有编译时保证 myfun ,并且您希望与 Gold 一起使用的所有其他函数始终提供为金比。程序输入(来自用户,网络或以往)仍然需要运行时检查,这就是 buildGold 提供的内容;显然,永远不会有一个程序,可以承诺人类不会输入不希望的东西。



在您的问题的评论中给出的替代方案也值得考虑。如果你需要的只是一个函数 myfun ,那么ADT的权重可能会稍大,如果失败,那么只需要 myfun ::(Integer,Integer) - >也许???


Sorry if the question is very elementary, I am still very new to Haskell. Lets say I have a function that can only work with two numbers that are in the golden ration (1.618), how do I define the types of myfun x y to take only golden ratio numbers. What happens if I invoke myfun without golden ratio numbers from within my program (a compile error?)? What happens if the call without golden ratio numbers is made at runtime via user input?

解决方案

You might want an ADT that can only be constructed with golden ratio numbers then write myfun to accept that data type.

I've assumed Integer as a base type, but you could use others (ex: Double or Float) or even be polymorphic.

1) Make the ADT

module Golden (Gold, getGold, buildGold) where

data Gold = G Integer Integer

getGold :: Gold -> (Integer, Integer)
getGold (G x y) = (x, y)

buildGold :: Integer -> Integer -> Maybe Gold
buildGold x y
    | isGolden x y = Just (G x y)
    | otherwise    = Nothing

Notice this module exports the Gold type but not the constructor (namely, not G). So the only way to get a value of type Gold is with buildGold which performs a run-time check - but only one - so the values of Gold can be used and assumed to be a golden ratio by all the consumers without checking.

2) Use the ADT to build myfun

myfun :: Gold -> ???
myfun g = expr
  where (x, y) = getGold g

Now if you try to call myfun with a non-golden number (a value not of type Gold) then you will get a compile time error.

Recap To build golden numbers buildGold function must be used, which forces the number to be checked.

Notice what gets checked when! You have a compile time guarantee that myfun, and all other functions you want to use with Gold, are always provided golden ratios. The program input (from user, network, or where ever) still needs runtime checks and that's what buildGold provides; obviously there's never going to be a program that can promise the human won't type something undesirable.

The alternatives given in the comments to your question are also worthy of consideration. An ADT is slightly heavy weight if all you need is a single function, myfun, that can fail then just have myfun :: (Integer, Integer) -> Maybe ???.

这篇关于使用Haskell的类型替换断言语句或者用其他语言进行检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆