Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 正整数型_Haskell - Fatal编程技术网

Haskell 正整数型

Haskell 正整数型,haskell,Haskell,在许多关于Haskell的文章中,他们说它允许在编译时而不是运行时进行一些检查。所以,我想实现最简单的检查——只允许对大于零的整数调用函数。我该怎么做呢?如果我没有插上Adam Gundry的预处理器,我将无法履行作为他的主管的职责,该预处理器负责管理Haskell的整数约束 module Positive (toPositive, Positive(unPositive)) where newtype Positive = Positive { unPositive :: Int } to

在许多关于Haskell的文章中,他们说它允许在编译时而不是运行时进行一些检查。所以,我想实现最简单的检查——只允许对大于零的整数调用函数。我该怎么做呢?

如果我没有插上Adam Gundry的预处理器,我将无法履行作为他的主管的职责,该预处理器负责管理Haskell的整数约束

module Positive (toPositive, Positive(unPositive)) where

newtype Positive = Positive { unPositive :: Int }

toPositive :: Int -> Maybe Positive
toPositive n = if (n < 0) then Nothing else Just (Positive n)
聪明的构造函数和抽象障碍都很好,但是它们将太多的测试推到了运行时,并且不允许您以静态检查的方式实际知道自己在做什么,而不需要填充。一个学究写道:“另一个答案的作者似乎认为0是肯定的,有些人可能会认为有争议。当然,事实上我们有各种下限,0和1都经常发生。我们也有一些上限的用法。) 按照Xi的DML的传统,Adam的预处理器在Haskell本机提供的基础上增加了一层额外的精度,但由此产生的代码会按原样擦除Haskell。如果他所做的能够更好地与GHC结合,与Iavor Diatchki所做的类型级自然数工作相协调,那将是一件好事。我们很想弄清楚什么是可能的

回到一般的观点,Haskell目前没有足够的依赖类型来允许通过理解构造子类型(例如,大于0的整数元素),但是您通常可以将类型重构为允许静态约束的索引版本。目前,单例类型构造是实现这一点的最干净的方法。您需要一种“静态”整数,然后这种类型的居民
Integer->*
捕获特定整数的属性,例如“具有动态表示”(这是单例构造,使每个静态事物都有一个唯一的动态对应项),但也有更具体的事情,如“正”


Inch代表了一种想象,如果您不需要为了处理一些行为合理的整数子集而费心于单例构造,它会是什么样子。依赖类型编程在Haskell中通常是可能的,但目前比必要的复杂得多。对这种情况的恰当看法是尴尬,我个人对此感觉最为强烈。

这或实际上,对一类自然数(包括0)的类似渴望实际上是对Haskell的数字类层次结构的常见抱怨,这使得不可能提供一个真正干净的解决方案

为什么??查看
Num
的定义:

class (Eq a, Show a) => Num a where
    (+) :: a -> a -> a
    (*) :: a -> a -> a
    (-) :: a -> a -> a
    negate :: a -> a
    abs :: a -> a
    signum :: a -> a
    fromInteger :: Integer -> a
除非您恢复使用
error
(这是一种不好的做法),否则您无法提供
(-
)、
否定
fromInteger

的定义,Haskell可以在编译时执行其他语言在运行时执行的一些检查。您的问题似乎暗示您希望在编译时取消任意检查,这在没有大量潜在的证明义务的情况下是不可能的(这可能意味着您,程序员,需要证明该属性对于所有用途都是正确的)

在下面的文章中,我不觉得我说的比pigworker在提到非常酷的
Inch
工具时提到的更多。希望每个主题上的附加文字能为您澄清一些解决方案空间

人们的意思(当谈到Haskell的静态保证时)

通常,当我听到人们谈论Haskell提供的静态保证时,他们谈论的是Hindley Milner风格的静态类型检查。这意味着不能将一种类型与另一种类型混淆——任何此类误用都是在编译时发现的(例如:
let x+1中的x=“5”无效)。显然,这只是表面现象,我们可以在Haskell中讨论静态检查的更多方面

智能构造函数:在运行时检查一次,通过类型确保安全

Gabriel的解决方案是使用一个类型,
Positive
,它只能是正数。生成正值仍然需要在运行时进行检查,但一旦获得正值,就不需要使用函数进行检查——静态(编译时)类型检查可以从这里开始使用

这是解决许多问题的好办法。我在讨论时也提出了同样的建议。无论如何,我不认为这是你想要的

精确表示法

dflemstr评论说,您可以使用一个类型,
Word
,它不能表示负数(与表示正数略有不同)。通过这种方式,您实际上不需要使用受保护的构造函数(如上所述),因为没有违反您的不变量的类型的居住者

使用正确表示的更常见示例是非空列表。如果您想要一个永远不能为空的类型,那么您可以创建一个非空列表类型:

data NonEmptyList a = Single a | Cons a (NonEmptyList a)
这与使用
Nil
而不是
单个a
的传统列表定义不同

回到正面的例子,您可以使用一种形式的Peano数字:

data NonNegative = One | S NonNegative
或者用户GADTs构建无符号二进制数(您可以添加
Num
,以及其他实例,允许使用
+
之类的函数):

外部证据

虽然不是Haskell宇宙的一部分,但可以使用替代系统(如Coq)生成Haskell,以说明和证明更丰富的属性。通过这种方式,Haskell代码可以简单地省略检查,如
x>0
,但x始终大于0这一事实将是一个静态保证(同样:安全性不是由Haskell造成的)

根据养猪工人的话,我
data NonNegative = One | S NonNegative
{-# LANGUAGE GADTs #-}

data Zero
data NonZero
data Binary a where
  I :: Binary a -> Binary NonZero
  O :: Binary a -> Binary a
  Z :: Binary Zero
  N :: Binary NonZero

instance Show (Binary a) where
        show (I x) = "1" ++ show x
        show (O x) = "0" ++ show x
        show (Z)   = "0" 
        show (N)   = "1"
{-@ myValue :: {v: Int | v > 0} #-}
myValue = 5
{-@ f :: {v: Int | v > 0 } -> Int @-}