Nif*_*dde 1 haskell functional-programming
我是 Haskell 的新手,我正在做一些练习来尽可能多地学习关于类型的知识,但有些问题对我来说真的很困惑。我正在苦苦挣扎的练习内容如下:
以下表达式的类型是什么?如果表达式没有类型,请尽可能多地说明。还要确保在需要时声明必要的类限制。
5 + 8 :: ?
(+) 2 :: ?
(+2) :: ?
(2+) :: ?
Run Code Online (Sandbox Code Playgroud)
我知道 5 + 8 将返回一个 Int,但其他人本身并不是有效的表达式。这是否意味着它们没有类型,还是我应该将它们视为函数 (f :: Int -> Int)(fx = x + 2)?
首先,答案:
5 + 8具有forall a. Num a => a可以专用于的类型Int。(+) 2和(2 +)是相同的,并且都具有forall a. Num a => a -> a可以专用于的类型Int -> Int。(+ 2)是不同的,但也有forall a. Num a => a -> a可以专门化的类型Int -> Int。(+)具有forall a. Num a => a -> a -> a可以专用于的类型Int -> Int -> Int。如需进一步说明,请继续阅读。
在Haskell,像数字文字114514并不能有一个具体的类型一样Int。这很好,因为我们有许多不同类型的数字,包括。Int, Integer, Float,Double等等,我们不希望每种类型都有不同的符号。
文字5, 114514, 和1919810都具有类型
forall a. Num a => a
Run Code Online (Sandbox Code Playgroud)
你可以这样读:“对于任何类型a,如果a是Num typeclass 的一个实例,那么值可以有 type a。” Int, Integer,Float和Double都是 , 的实例Num,并且因为 Haskell 具有(相对)强类型推断,在不同的上下文中它将专门用于具体类型,如Int.
那么什么是类型类呢?
我们在 Haskell 中表达某种类型“支持”某些操作的方式是通过typeclasses。类型类是一组函数签名,没有真正的实现。它们代表我们要对某些类型进行的Num操作(例如代表我们要对数字类型进行的操作),但不同类型的实际实现可能有所不同(整数和浮点数的实际计算确实不同)。
我们可以通过为该类型实际定义这些函数来使类型成为instance类型类的an (注意,这与面向对象编程中的实例和类无关)。这样,我们定义了这个类型来支持这些操作。
Num是类型类之一,表示支持数字运算。它的部分定义如下(为了减少冗长,我没有把完整的放在这里):
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
Run Code Online (Sandbox Code Playgroud)
你可以看到在签名中我们有as 而不是真正的具体类型,这些函数被称为是多态的,也就是说,它们是通用的,可以专门用于不同的类型。
例如,如果a和b都是Ints,那么a + b也有类型Int,因为 Haskell 推断+我们这里使用的 应该是为 定义的Int那个,因为它的两个参数都是Ints。
因此,如果某个类型是 的实例Num,则意味着为该类型定义了+, -and*运算符。作为Num支持这些运营商的手段的一个实例。
Haskell 的一个好处是它(相对)灵活的中缀运算符。在 Haskell 中,中缀运算符只不过是带有中缀符号(这只是一种语法糖)的普通函数。我们还可以以前缀方式使用中缀运算符。例如,5 + 8相当于(+) 5 8。
您似乎对(+) 5,(+5)和感到困惑(5+)。请记住,如果我们将括号放在中缀函数的两侧,我们将其设为前缀。而且你可能已经知道,前缀函数可以部分应用,即只给函数一些参数,这样就变成了一个参数较少的函数,以后再给。(+) 5意味着我们部分应用(+)只给它的第一个参数,所以它成为另一个的功能等待一个参数,或者原本其第二个参数。我们可以应用(+) 5到8所以它变成((+) 5) 8,它等价于5 + 8。
另一方面,(5+)和(+5)被称为部分,这是中缀运算符的另一种语法糖。(5+)意味着您填充了运算符的左侧,并且它成为等待其右侧的函数。(5+) 8意味着5 + 8或(+) 5 8。(+5)被翻转,即你填充了右手边,所以它是一个等待左手边的函数。(+5) 8意味着8 + 5或(+) 8 5。
Haskell 是一种与你可能学过的其他语言非常不同的语言。编译的每个表达式都有一个类型。函数是一流的,每个函数也有一个类型。按类型思考将真正有助于您的学习进度。