Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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 为什么一些Data.List.Split函数使用'Int'而其他函数使用'Integral a'?_Haskell - Fatal编程技术网

Haskell 为什么一些Data.List.Split函数使用'Int'而其他函数使用'Integral a'?

Haskell 为什么一些Data.List.Split函数使用'Int'而其他函数使用'Integral a'?,haskell,Haskell,以下是来自Data.List.Split的类型签名: chunksOf :: Int -> [e] -> [[e]] splitPlaces :: Integral a => [a] -> [e] -> [[e]] 为什么有些函数(如chunksOf)使用Int,而另一些函数(如splitPlaces)使用更通用的Integral a?在这个答案中,我试图找出接口不一致的历史原因。概要:Brent似乎在运行中使一些函数更通用,以帮助制定QuickCheck属性 为

以下是来自
Data.List.Split的类型签名:

chunksOf :: Int -> [e] -> [[e]]
splitPlaces :: Integral a => [a] -> [e] -> [[e]]

为什么有些函数(如
chunksOf
)使用
Int
,而另一些函数(如
splitPlaces
)使用更通用的
Integral a

在这个答案中,我试图找出接口不一致的历史原因。概要:Brent似乎在运行中使一些函数更通用,以帮助制定QuickCheck属性

为什么
splitPlaces
是通用的? Brent似乎推广了
splitPlaces
的类型,以便更容易为该函数引入QuickCheck属性。QuickCheck属性使用新类型包装器来控制测试用例的生成,并且使用
Integral a
约束,
splitPlaces
可以通过这个新类型包装器查看算术运算。另见:

  • 这概括了
    splitPlaces
    的类型,并引入了快速检查属性

  • 关于这些新型包装

但是,以下是关于
splitPlaces
的属性之一:

prop_splitPlaces_preserve :: [NonNegative Integer] -> [Elt] -> Bool
prop_splitPlaces_preserve ps l = concat (splitPlaces ps' l) == genericTake (sum ps') l
  where ps' = map unNN ps
请注意,快速检查会自动生成列表
ps
,该列表在传递到
splitPlaces
之前由
map unNN ps
转换。
unNN
函数删除
非负
包装,因此
splitPlaces
不必处理
非负
包装本身。但是,它接收的参数类型是
[Integer]
,而不是
[Int]
,因此它在数值类型中仍然需要是泛型的

[非负整数]
代替
[非负整数]
有什么意义? 我怀疑
[Int]
的属性为false,因为计算和时出现算术溢出。该属性甚至可能被QuickCheck伪造,因为
任意[NonNegative Integer]
实例最终将委托给该实例,该实例可以生成非常大的值

我想使用
[非负整数]
可以从两个方面解决这个问题:

  • 使用
    整数
    ,不会发生溢出
  • 任意整数
    实例委托给只生成小值的实例
  • 所以我猜允许任意整数类型的原因是,QuickCheck属性对于
    Int
    会失败,但是对于
    Integer
    会成功

    为什么
    chunksOf
    不是通用的?
    chunksOf
    的属性使用模式匹配删除新类型包装。另见:

    • 这将为
      splitEvery
      引入属性

    • splitEvery
      重命名为
      chunksOf

    以下是关于
    chunksOf
    的属性之一:

    prop_chunksOf_all_n :: Positive Int -> NonEmptyList Elt -> Bool
    prop_chunksOf_all_n (Positive n) (NonEmpty l) = all ((==n) . length) (init $ chunksOf n l)
    
    请注意,此属性与QuickCheck自动生成的参数匹配,并将其传递给
    chunksOf
    ,而不使用newtype包装器。对于测试
    chunksOf
    所需的参数,这很容易做到,因为这些数字没有嵌套在其他类型中。与上面的
    prop\u splitPlaces\u preserve
    相比,将
    [非负整数]
    转换为
    [整数]
    [Int]
    需要比模式匹配更复杂的东西


    arbitral Int
    arbitral Integer
    之间的差异在这里并不重要,因为该属性不涉及任何可能触发算术溢出的操作。

    问得好!从接口的角度来看,我看不出有什么特别好的理由——也许只是实现起来稍微简单一点。可以使用标准化。两者中哪一个更好取决于前景,分歧将比比皆是。