为什么产品有界?

时间:2019-04-20 09:20:42

标签: haskell bounded-types

http://learnyouahaskell.com/functors-applicative-functors-and-monoids

  

sequence [] = return [] sequence (a:as) = do x <- a fmap (x:) $ sequence as 的定义如下:

Product

为什么newtype Product a = Product { getProduct :: a } deriving (Eq, Ord, Read, Show, Bounded) 被迫Product

同一本书中的以下几段内容:

  

它的Bounded实例看起来像这样:

Monoid

嗯?唯一的约束是instance Num a => Monoid (Product a) where mempty = Product 1 Product x `mappend` Product y = Product (x * y) !但是Num a特别意味着Num,而且AFAIK不受限制(与Integer不同)。

然后进行测试:

Int

让我们看看下面的代码:

import Data.Monoid

numbers :: [Integer]
numbers = [1..100]

main = print (getProduct . mconcat . map Product $ numbers)

工作。不会失败。

那么m@m-X555LJ:~$ runhaskell wtf.hs 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 m@m-X555LJ:~$ 的界限是什么? Product有界限吗?

让我们再次播放:

Product

看来m@m-X555LJ:~$ ghci GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help Prelude> minBound :: Int -9223372036854775808 Prelude> maxBound :: Int 9223372036854775807 Prelude> import Data.Monoid Prelude Data.Monoid> maxBound :: (Product Integer) <interactive>:4:1: error: • No instance for (Bounded Integer) arising from a use of ‘maxBound’ • In the expression: maxBound :: Product Integer In an equation for ‘it’: it = maxBound :: Product Integer Prelude Data.Monoid> maxBound :: Product <interactive>:5:13: error: • Expecting one more argument to ‘Product’ Expected a type, but ‘Product’ has kind ‘* -> *’ • In an expression type signature: Product In the expression: maxBound :: Product In an equation for ‘it’: it = maxBound :: Product Prelude Data.Monoid> maxBound :: (Product Int) Product {getProduct = 9223372036854775807} Prelude Data.Monoid> Leaving GHCi. m@m-X555LJ:~$ 本身并不是ProductBounded是;但是Int抛出! IIUC maxBound :: (Product Integer)Product deriving BoundedmaxBound上定义良好的保证。显然,并非总是如此。

那为什么ProductProduct的实例?

1 个答案:

答案 0 :(得分:6)

Product不是Bounded的实例(无论如何,这都是一种错误)。您错过了deriving的实际用途。

Haskell报告中有a formal specification of derived instances

  

如果 T 是由以下内容声明的代数数据类型:

     

data cx => T u1uk = K1 t11t1k1 | ⋅⋅⋅ | Kn tn1tnkn
                     deriving (C1, …, Cm)

     

(其中 m≥0 ,并且如果 m = 1 可以省略括号),则可能为类 C 如果满足以下条件:

     
      
  1. C EqOrdEnumBoundedShowRead之一。
  2.   
  3. 存在一个上下文 cx',使得对于每个构成类型 t <, cx'⇒C t ij sub> ij
  4.   
     

[...]

     

每个派生的实例声明将具有以下形式:instance (cx, cx′) => Ci (T u1uk) where { d } [...]

这意味着类约束自动分配给类型参数。

the section on Bounded中所述:

  

Bounded类引入了类方法minBoundmaxBound,它们定义了类型的最小和最大元素。对于枚举,data声明中列出的第一个和最后一个构造函数是界限。对于具有单个构造函数的类型,该构造函数将应用于构成类型的边界。例如,以下数据类型:

data  Pair a b = Pair a b deriving Bounded
     

将生成以下Bounded实例:

instance (Bounded a,Bounded b) => Bounded (Pair a b) where  
  minBound = Pair minBound minBound  
  maxBound = Pair maxBound maxBound

对于Product,这意味着Product a仅是Bounded的实例,如果a是。