如果我对以下表达式进行 beta-reduce:
foldr (mappend . Sum) 1 [2]
= (mappend . Sum) 2 (foldr (mappend . Sum) 1 [])
= (mappend . Sum) 2 1
= mappend (Sum 2) 1
...
Run Code Online (Sandbox Code Playgroud)
查看类型:
// mappend (<>) :: Monoid a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)
我们可以看到最后一行有一个类型错误,因为常量1应该属于Monoid类(但事实并非如此)。
不过,ghci并不抱怨。
为什么要检查表达式类型?
简短回答:1被解释为 a Sum a,因此您的foldr 的类型是:
foldr (mappend . Sum) 1 [2] :: Num a => Sum a
Run Code Online (Sandbox Code Playgroud)
其中2has typea和1has type Sum a。
Sum a是一个实例Numifa是一个实例Num,事实上,源代码显示 [src]:
newtype Sum a = Sum { getSum :: a }
deriving ( Eq -- ^ @since 2.01
, Ord -- ^ @since 2.01
, Read -- ^ @since 2.01
, Show -- ^ @since 2.01
, Bounded -- ^ @since 2.01
, Generic -- ^ @since 4.7.0.0
, Generic1 -- ^ @since 4.7.0.0
, Num -- ^ @since 4.7.0.0
)
Run Code Online (Sandbox Code Playgroud)
因此,这意味着如果您编写一个整数文字,例如1,它可以被构造为Sum a任何 的a实例Num,因此1 :: Sum Integer也是Sum 1。
因此,这意味着1您的foldr具有 type Sum a,因此例如:
mappend (Sum 2 :: Sum Integer) (1 :: Sum Integer)
-> Sum (2 + 1)
-> Sum 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |