'where'中的类型声明 - 发生了什么?

Mat*_*ick 14 haskell types where-clause

在阅读QuickCheck手册时,我遇到了以下示例:

prop_RevRev xs = reverse (reverse xs) == xs
  where types = xs::[Int]
Run Code Online (Sandbox Code Playgroud)

手册继续说:

属性必须具有单形类型."多态"属性(例如上面的属性)必须限制为用于测试的特定类型.通过在a中声明一个或多个参数的类型来方便

其中types =(x1 :: t1,x2 :: t2,...)

条款.请注意,类型不是关键字; 这只是一个本地声明,它提供了一个方便的地方来限制x1,x2等的类型.

我之前从未在Haskell中看过这样的技巧.这是我真正遇到的问题:

  1. 为什么类型声明的这种语法甚至存在?以下哪些不能对我做什么?

    prop_RevRev :: [Int] -> Bool
    prop_RevRev xs = reverse (reverse xs) == xs
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这种用法是否where构成了类型声明的"特殊"语法?或者它是否一致和合乎逻辑(如果是这样,如何?)?

  3. 这是使用标准还是传统的Haskell?

dav*_*420 14

where不是类型声明的特殊语法.例如,这有效:

prop_RevRev :: [Int] -> Bool
prop_RevRev xs = ys == xs
  where ys = reverse (reverse xs)
Run Code Online (Sandbox Code Playgroud)

这样做:

prop_RevRev xs = ys == xs
  where ys = reverse (reverse xs)
        ys :: [Int]
Run Code Online (Sandbox Code Playgroud)

的优势where type = (xs :: [Int])prop_RevRev :: [Int] -> Bool的是,在后一种情况下,你必须指定返回类型,而在前者的情况下,编译器可以推断出它.如果你有非Boolean财产,这很重要,例如:

prop_positiveSum xs = 0 < length xs && all (0 <) xs ==> 0 < sum xs
  where types = (xs :: [Int])
Run Code Online (Sandbox Code Playgroud)